React sẽ không tải hình ảnh cục bộ


122

Tôi đang xây dựng một ứng dụng phản ứng nhỏ và hình ảnh cục bộ của tôi sẽ không tải. Hình ảnh như placehold.it/200x200tải. Tôi nghĩ có lẽ nó có thể là một cái gì đó với máy chủ?

Đây là App.js của tôi

import React, { Component } from 'react';

class App extends Component {
    render() {
        return (
            <div className="home-container">
                <div className="home-content">
                    <div className="home-text">
                        <h1>foo</h1>
                    </div>
                    <div className="home-arrow">
                        <p className="arrow-text">
                            Vzdělání
                        </p>
                        <img src={"/images/resto.png"} />
                    </div>
                </div>
            </div>
        );
    }
}

export default App;

index.js:

import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, Link } from 'react-router';
import { createHistory } from 'history';
import App from './components/app';

let history = createHistory();

render(
    <Router history={history} >
        <Route path="/" component={App} >
            <Route path="vzdelani" component="" />
            <Route path="znalosti" component="" />
            <Route path="prace" component="" />
            <Route path="kontakt" component="" />
        </Route>
        <Route path="*" component="" />
    </Router>,
    document.getElementById('app')
);

và server.js:

var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.config.dev');

var app = express();
var compiler = webpack(config);

app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}));

app.use(require('webpack-hot-middleware')(compiler));

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, 'localhost', function(err) {
  if (err) {
    console.log(err);
    return;
  }

  console.log('Listening at http://localhost:3000');
});

4
Điều này thường có nghĩa là máy chủ web cục bộ của bạn không cung cấp hình ảnh hoặc url bạn chỉ định không chính xác. Mở bảng điều khiển trình duyệt của bạn và kiểm tra xem bạn có gặp bất kỳ lỗi nào như 404 không.
Mario Tacke

5
Mọi người! chỉ sử dụng require(). ví dụ: src = {
request

Câu trả lời:


268

Khi sử dụng Webpack bạn cần phải requirehình ảnh để cho Webpack để xử lý chúng, trong đó sẽ giải thích lý do tại sao bên ngoài hình ảnh tải trong khi nội bộ không, nên thay vì <img src={"/images/resto.png"} />bạn cần phải sử dụng <img src={require('/images/image-name.png')} />thay thế hình ảnh name.png với tên hình ảnh chính xác cho mỗi người trong số họ. Bằng cách đó, Webpack có thể xử lý và thay thế nguồn img.


1
Nhưng làm thế nào để nhập khẩu yêu cầu? Xác minh? Nếu có, thì làm thế nào? Tôi đã thử import {require} from 'browserify'. Nhưng nó không hoạt động.
Shubham Kushwah

1
@ShubhamKushwah Bạn không cần phải nhập require. Nó được cung cấp như một phần của commonjs. Xem stackoverflow.com/a/33251937/4103908viget.com/articles/gulp-browserify-starter-faq để biết thêm thông tin chi tiết có thể giúp bạn sử dụng requestBrowserify bằng Gulp.
Thomas

@Thomas Vấn đề là với hình ảnh bên trong cũng như bên ngoài, chúng sẽ không tải khi trang tải lần đầu tiên, nhưng nếu tôi làm mới nó, chúng sẽ tải. Vậy tôi nên giải quyết điều này như thế nào - Xin hãy giúp đỡ!
Shubham Kushwah

6
Nhận được một lỗi: Module not found: Error: Can't resolve 'MyPNG.png' in 'C:...\app\components\images'. Đường dẫn đến tệp có vẻ tốt !.
reubenjohn

2
src = {request ('./ reactLogo.svg')} bắt đầu đường dẫn của bạn bằng "./" cho thư mục hiện tại để tránh lỗi.
pho mát

53

Tôi bắt đầu xây dựng ứng dụng của mình bằng create-react-app (xem tab "Tạo ứng dụng mới"). README.md đi kèm với nó đưa ra ví dụ sau:

import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image

console.log(logo); // /logo.84287d09.png

function Header() {
  // Import result is the URL of your image
  return <img src={logo} alt="Logo" />;
}

export default Header;

Điều này làm việc hoàn hảo cho tôi. Đây là liên kết đến tài liệu chính cho README đó, giải thích (phần trích dẫn):

... Bạn có thể nhập tệp ngay trong mô-đun JavaScript. Điều này yêu cầu Webpack đưa tệp đó vào gói. Không giống như nhập CSS, nhập tệp cung cấp cho bạn một giá trị chuỗi. Giá trị này là đường dẫn cuối cùng mà bạn có thể tham chiếu trong mã của mình, ví dụ như thuộc tính src của một hình ảnh hoặc href của một liên kết đến một tệp PDF.

Để giảm số lượng yêu cầu tới máy chủ, việc nhập hình ảnh nhỏ hơn 10.000 byte sẽ trả về một URI dữ liệu thay vì một đường dẫn. Điều này áp dụng cho các phần mở rộng tệp sau: bmp, gif, jpg, jpeg và png ...


Ngoài ra, bạn cũng phải xuất hình ảnh từ một nơi nào đó để có thể nhập chúng ở bất kỳ đâu chứ không chỉ từ trong cùng một thư mục, đó sẽ là trường hợp nào nếu chúng không được xuất. Chúng sẽ phải nằm trong cùng một thư mục với thành phần mà chúng đang được nhập vào. Bạn sẽ nhận thấy rằng với bất kỳ ứng dụng React mới nào được tạo bằng CRA chẳng hạn, tệp logo.svg nằm trong cùng thư mục với App.js, nơi nó được nhập. Tôi đã viết một mảnh trên nhập khẩu hình ảnh trong Phản ứng ở đây: blog.hellojs.org/importing-images-in-react-c76f0dfcb552
Maria Campbell

Để theo dõi nhận xét ở trên, nếu bạn sử dụng trình tải url webpack như fandro hiển thị ở trên, các tệp phù hợp với phần mở rộng thử nghiệm trong webpack sẽ tự động được xuất và làm cho chúng có sẵn để nhập lưu mà Hawkeye Parker đã hiển thị ở trên.
dave4jr

Tôi biết đây là một chủ đề thực sự cũ nhưng vẫn còn; làm thế nào bạn làm cho nó hoạt động? Trong trường hợp của tôi, chương trình đang cố gắng "đọc hình ảnh" ... dẫn đến một lỗi khủng khiếp: Unexpected character '�' (1:0) > 1 | �PNG | ^ 2 | 3 | 4 | IHDR��r~ipHYs���o�d��IDATx^�}���Ü�d7�w¿½ï¿½ ��JzH!�K�ï...
V. Courtois

@ V.Courtois xin lỗi - tôi đã không làm việc với công cụ này kể từ đó và tôi không nhớ thêm bất kỳ chi tiết nào ngay bây giờ :(
Hawkeye Parker

Tôi phải thêm hình ảnh của mình vào thư mục chung trong dự án Create-React-App.
pixel 67

29

Một cách khác để làm:

Đầu tiên, cài đặt các module: url-loader,file-loader

Sử dụng npm: npm install --save-dev url-loader file-loader

Tiếp theo, thêm cái này vào cấu hình Webpack của bạn:

module: {
    loaders: [
      { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
    ]
  }

limit: Giới hạn byte đối với tệp nội tuyến dưới dạng URL dữ liệu

Bạn cần cài đặt cả hai mô-đun: url-loaderfile-loader

Cuối cùng, bạn có thể làm:

<img src={require('./my-path/images/my-image.png')}/>

Bạn có thể điều tra thêm các trình tải này tại đây:

url-loader: https://www.npmjs.com/package/url-loader

trình tải tệp: https://www.npmjs.com/package/file-loader


1
Hy vọng rằng nó sẽ giúp những người khác. Tôi cũng phải làm điều này; Cài đặt trình tải url. npm install --save-dev url-loader
LUser

1
Tôi đã đấu tranh với điều này đêm qua, và bài đăng này thực sự đã xuất hiện trên màn hình của tôi sáng nay :) Nếu bạn thấy điều gì đó giống như vậy Module build failed: SyntaxError: c:/contrivedpath/images/profile.jpg: Unexpected character '�' (1:0), tất cả những gì bạn cần làm là thêm cấu hình trình tải url ở trên vào cấu hình webpack của bạn, cài đặt npm url-loaderAND file-loadervà bạn sẽ có chức năng. Tôi đã kiểm tra để đảm bảo chắc chắn và trình tải tệp là cần thiết.
agm1984

1
@ agm1984 Tôi đã làm theo các bước trên và vẫn nhận được ERROR in ./src/images/imagename.png Module parse failed: Unexpected character '�' (1:0)thông báo. Có ý kiến ​​gì không?
David

nó thực sự hữu ích nhưng tôi không thể hiểu tại sao <img src = "images / myimage.png" /> không hoạt động !! Bạn có thể vui lòng giải thích?
Đánh dấu

Đã làm tất cả những gì bạn nói nhưng không có xúc xắc. Webpack xây dựng mà không phàn nàn, tôi có thể thấy hình ảnh PNG của tôi đã được chuyển vào thư mục đầu ra nhưng hình ảnh không tải trên trang. Khi tôi kiểm tra mã, nó chỉ nói src=[Object module]và khi tôi di chuột, nó thông báo 'không thể tải hình ảnh'
JSStuball

4

Thực sự tôi muốn bình luận, nhưng tôi chưa được phép. Đó là lý do tại sao đó giả vờ là câu trả lời tiếp theo trong khi nó không phải.

import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png

function Header() {
// Import result is the URL of your image
  return <img src={logo} alt="Logo" />;

Tôi muốn tiếp tục con đường đó. Điều đó hoạt động trơn tru khi người ta có hình ảnh người ta có thể chèn đơn giản. Trong trường hợp của tôi, điều đó phức tạp hơn một chút: Tôi phải lập bản đồ một số hình ảnh. Cho đến nay, cách duy nhất khả thi để làm điều này mà tôi tìm thấy là như sau

import upperBody from './upperBody.png';
import lowerBody from './lowerBody.png';
import aesthetics from './aesthetics.png';

let obj={upperBody:upperBody, lowerBody:lowerBody, aesthetics:aesthetics, agility:agility, endurance:endurance}

{Object.keys(skills).map((skill) => {
 return ( <img className = 'icon-size' src={obj[skill]}/> 

Vì vậy, câu hỏi của tôi là liệu có cách nào đơn giản hơn để xử lý những hình ảnh này không? Không cần phải nói rằng trong trường hợp tổng quát hơn, số lượng tệp phải được nhập theo nghĩa đen có thể rất lớn và số lượng khóa trong đối tượng cũng vậy. (Đối tượng trong mã đó được liên quan rõ ràng để tham chiếu bằng các khóa tên -its) Trong trường hợp của tôi, các thủ tục liên quan đến yêu cầu đã không hoạt động - trình tải tạo ra các lỗi lạ trong quá trình cài đặt và không có dấu hiệu hoạt động; và bản thân yêu cầu cũng không hoạt động.


2

Tôi chỉ muốn để lại phần sau để nâng cao câu trả lời được chấp nhận ở trên.

Ngoài câu trả lời được chấp nhận, bạn có thể làm cho cuộc sống của mình dễ dàng hơn một chút bằng cách chỉ định một aliasđường dẫn trong Webpack, vì vậy bạn không phải lo lắng về vị trí của hình ảnh so với tệp bạn đang ở. Vui lòng xem ví dụ bên dưới :

Tệp Webpack:

module.exports = {
  resolve: {
    modules: ['node_modules'],
    alias: {
      public: path.join(__dirname, './public')
    }
  },
}

Sử dụng:

<img src={require("public/img/resto.ong")} />

2

Tôi cũng muốn thêm vào câu trả lời từ @Hawkeye Parker và @Kiszuriwalilibori:

Như đã được lưu ý từ các tài liệu ở đây , tốt nhất là nhập các hình ảnh khi cần.

Tuy nhiên, tôi cần nhiều tệp được tải động, điều này khiến tôi phải đặt hình ảnh vào thư mục công cộng ( cũng được nêu trong README ), vì đề xuất này dưới đây từ tài liệu:

Thông thường, chúng tôi khuyên bạn nên nhập biểu định kiểu, hình ảnh và phông chữ từ JavaScript. Thư mục chung hữu ích như một giải pháp thay thế cho một số trường hợp ít phổ biến hơn:

  • Bạn cần một tệp có tên cụ thể trong đầu ra bản dựng, chẳng hạn như tệp kê khai.webmanifest.
  • Bạn có hàng nghìn hình ảnh và cần tham chiếu động các đường dẫn của chúng.
  • Bạn muốn bao gồm một tập lệnh nhỏ như speed.js bên ngoài mã đi kèm.
  • Một số thư viện có thể không tương thích với Webpack và bạn không có lựa chọn nào khác ngoài việc đưa nó vào làm thẻ.

Hy vọng rằng sẽ giúp ai đó khác! Để lại cho tôi một bình luận nếu tôi cần xóa bất kỳ điều gì trong số đó.


2

Tôi đang phát triển một dự án sử dụng SSR và bây giờ tôi muốn chia sẻ giải pháp của mình dựa trên một số câu trả lời ở đây.

Mục tiêu của tôi là tải trước một hình ảnh để hiển thị khi kết nối Internet ngoại tuyến. (Nó có thể không phải là phương pháp hay nhất, nhưng vì nó phù hợp với tôi nên bây giờ vẫn ổn) FYI, tôi cũng sử dụng ReactHooks trong dự án này.

  useEffect(() => {
    // preload image for offline network
    const ErrorFailedImg = require('../../../../assets/images/error-review-failed.jpg');
    if (typeof window !== 'undefined') {
      new Image().src = ErrorFailedImg;
    }
  }, []);

Để sử dụng hình ảnh, tôi viết nó như thế này

<img src="/assets/images/error-review-failed.jpg" />

1

Hãy thử thay đổi mã trong server.js thành -

app.use(require('webpack-dev-middleware')(compiler, {
      noInfo: true,
      publicPath: config.output.path
    }));

1

Đôi khi bạn có thể nhập thay vì nhập vào vị trí hình ảnh của mình / src: try

./assets/images/picture.jpg

thay vì

../assets/images/picture.jpg

1
src={"/images/resto.png"}

Sử dụng thuộc tính src theo cách này có nghĩa là, hình ảnh của bạn sẽ được tải từ đường dẫn tuyệt đối "/images/resto.png" cho trang web của bạn. Thư mục hình ảnh phải được đặt ở thư mục gốc của trang web của bạn. Ví dụ: http://www.example.com/images/resto.png


1

Đây là những gì đã làm việc cho tôi. Trước tiên, chúng ta hãy hiểu vấn đề. Bạn không thể sử dụng một biến làm đối số để yêu cầu. Webpack cần biết những tệp nào cần đóng gói tại thời điểm biên dịch.

Khi tôi gặp lỗi, tôi nghĩ nó có thể liên quan đến vấn đề đường dẫn như trong trường hợp tuyệt đối và tương đối. Vì vậy, tôi đã chuyển một giá trị được mã hóa cứng để yêu cầu như dưới đây: <img src = {request ("../ asset / images / photosnap.svg")} alt = "" />. Nó đã hoạt động tốt. Nhưng trong trường hợp của tôi, giá trị là một biến đến từ các đạo cụ. Tôi đã cố gắng chuyển một biến chuỗi ký tự như một số đề xuất. Nó đã không hoạt động. Ngoài ra, tôi đã cố gắng xác định một phương thức cục bộ bằng cách sử dụng trường hợp chuyển đổi cho tất cả 10 giá trị (tôi biết đó không phải là giải pháp tốt nhất, nhưng tôi chỉ muốn nó hoạt động bằng cách nào đó). Điều đó cũng không hoạt động. Sau đó, tôi biết rằng chúng ta KHÔNG thể chuyển biến cho yêu cầu.

Để giải quyết vấn đề, tôi đã sửa đổi dữ liệu trong tệp data.json để giới hạn nó chỉ với tên hình ảnh của tôi. Tên hình ảnh này đến từ các đạo cụ dưới dạng chữ Chuỗi. Tôi đã nối nó với giá trị được mã hóa cứng, như sau:

import React from "react";

function JobCard(props) {  

  const { logo } = props;
  
  return (
      <div className="jobCards">
          <img src={require(`../assets/images/${logo}`)} alt="" /> 
      </div>
    )
} 
  

Giá trị thực có trong biểu trưng sẽ đến từ tệp data.json và sẽ tham chiếu đến một số tên hình ảnh như photosnap.svg.


0

Cách tốt nhất để tải hình ảnh cục bộ trong phản ứng là như sau

Ví dụ: Giữ tất cả hình ảnh của bạn (hoặc bất kỳ nội dung nào như video, phông chữ) trong thư mục chung như hình dưới đây.

nhập mô tả hình ảnh ở đây

Chỉ cần viết <img src='/assets/images/Call.svg' />để truy cập hình ảnh Call.svg từ bất kỳ thành phần phản ứng nào của bạn

Lưu ý: Giữ nội dung của bạn trong thư mục công khai đảm bảo rằng, bạn có thể truy cập nó từ bất kỳ đâu trong dự án, chỉ bằng cách cho '/ path_to_image' và không cần bất kỳ đường dẫn nào '../../' như thế này


Hình ảnh PNG sẽ không hoạt động trên này? Bcuz tôi đã làm chính xác điều này và nó không hoạt động.
maverick

PNG cũng sẽ hoạt động. SVG có làm việc cho bạn không? Vui lòng kiểm tra lỗi chính tả của tên tệp và đảm bảo rằng đường dẫn hình ảnh là chính xác.
mokesh moha

1
xin lỗi vì sai lầm này. Tôi chưa quen với phản ứng và tôi không biết rằng tệp thành phần phải bắt đầu bằng cách viết hoa. Sau đó nó hoạt động.
maverick

0

bạn phải nhập hình ảnh trước rồi sử dụng nó. Nó đã làm việc cho tôi.


import image from '../image.png'

const Header = () => {
   return (
     <img src={image} alt='image' />
   )
}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.