React, Node, Express를 사용하여 사진을 업로드하고 제공하는 방법

16367 단어 reactnodejavascript
이 블로그에서는 Express를 사용하여 React 클라이언트에서 노드 서버로 사진을 업로드하는 가장 간단하고 빠른 방법과 해당 사진을 다시 클라이언트에 표시하는 방법을 살펴보겠습니다.

앱의 이러한 구성 요소가 이미 설정되고 연결되어 있다고 가정하고 먼저 기본 버튼과 선택한 파일을 처리하는 기능부터 시작하겠습니다.

<input type="file" name="file" onChange={this.uploadHandler}/>



uploadHandler(event) {
  // code goes here
}

이 데모에서는 클래스 구성 요소를 사용하는 예제를 보여주지만 기능적 구성 요소에서도 이 작업을 수행할 수 있습니다.

이제 업로드 핸들러 기능 내에서 파일을 POST 요청으로 보낼 수 있는 것으로 변환한 다음 서버로 보내야 합니다. 이 예제에서는 Axios를 사용합니다.

업로드 핸들러 기능은 다음과 같습니다.

  uploadHandler(event) {
    const data = new FormData();
    data.append('file', event.target.files[0]);

    axios.post('/upload', data)
      .then((res) => {
        this.setState({ photos: [res.data, ...this.state.photos] });
      });
  }

여기서는 FormData의 인스턴스를 만들고 .append()로 파일을 추가합니다. 파일 세부 정보는 event.target.files[0] 의 콘솔 로그로도 볼 수 있습니다. 이 경우 다음과 같은 내용이 표시될 수 있습니다.


이제 Express 서버의 경우 아직 Multer가 없는 경우 npm install multer 명령을 통해 Multer를 설치해야 합니다. 그런 다음 POST 경로가 될 위치에 위의 Express 서버에 대한 .js 파일에 다음을 추가하십시오.

const multer = require('multer')

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'public')
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + '-' +file.originalname)
  }
})

const upload = multer({ storage: storage }).single('file')

여기에서 실제로 필요한 것은 upload 및 그 위에 있는 storage에서 빌드된 multer 함수입니다. 위의 multer.diskStorage 객체에서 'destination:'의 'public' 문자열은 사진을 저장할 폴더 이름을 원하는 대로 변경할 수 있습니다. 이 폴더는 기본적으로 전체 앱의 루트 폴더에 있습니다.
또한 그 아래의 Date.now() + '-' +file.originalname는 저장된 사진이 저장될 파일 이름을 지정합니다. 그대로 두면 원래 파일 이름이 유지되지만 JavaScript 형식의 날짜 앞에 대시가 붙습니다.

이제 POST 경로의 경우:

app.post('/upload', (req, res) => {
  upload(req, res, (err) => {
    if (err) {
      res.sendStatus(500);
    }
    res.send(req.file);
  });
});

보시다시피 앞서 언급한 upload() 함수는 이제 초기 Express app.post 에서 req 및 res 객체를 처리합니다. 파일을 저장할 수 없는 경우 500을 전송하여 기본적인 오류 처리가 있지만 그렇지 않은 경우 저장된 파일에 대한 정보를 다시 전송합니다. 실제로 해당 파일을 클라이언트에 다시 제공하기 위해 이제 서버가 필요로 하는 것은 한 가지뿐입니다.

app.use(express.static('public'));

익스프레스 서버 index.js 파일의 맨 아래에 이것을 추가하십시오. 여기에서 다시 '공용' 문자열은 이미지 파일을 저장할 폴더의 이름을 무엇이든 가리킵니다. 이제 클라이언트의 Axios 요청을 다시 살펴보겠습니다.

axios.post('/upload', data)
      .then((res) => {
        this.setState({ photos: [res.data, ...this.state.photos] });
      });
.then() , res.data 에는 저장된 파일에 대한 세부 정보가 포함된 개체가 포함되어 있으며 그 중 하나는 파일 이름입니다. this.setState({ photos: [res.data, ...this.state.photos] });는 이 객체를 this.state의 'photos' 배열 앞에 추가합니다.

이제 render() 의 업로드 버튼 아래에 다음과 같이 추가할 수 있습니다. (여기서 localhost는 앱이 제공되는 호스트이고 3000는 포트 번호입니다.)

        {this.state.photos.map(photo => (
          <img src={`http://localhost:3000/${photo.filename}`} />
        ))}

기본적으로 app.use(express.static('public')) 를 사용하면 'public' 폴더 내의 사진을 '/' 엔드포인트와 파일 이름에서 사용할 수 있습니다. 따라서 위의 지도 기능은 이제 사진을 추가할 때 사진을 하나씩 표시해야 합니다. 역순으로 추가하므로 가장 최근 사진이 맨 위에 표시됩니다.

다음은 클라이언트 측 앱에 대한 코드의 최종 결과입니다.

import React, { Component } from 'react';
import axios from 'axios';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      photos: [],
    };

  this.uploadHandler = this.uploadHandler.bind(this);
  }

  uploadHandler(event) {
    const data = new FormData();
    data.append('file', event.target.files[0]);
    axios.post('/upload', data)
      .then((res) => {
        this.setState({ photos: [res.data, ...this.state.photos] });
      });
  }

  render() {
    return  (
      <div>
        <div>
          <input type="file" name="file" onChange={this.uploadHandler}/>
        </div>
        {this.state.photos.map(photo => (
          <img src={`http://localhost:3000/${photo.filename}`} />
        ))}
      </div>
    )
  }
}

export default App;

내가 한 데모는 React, Node 및 Express와 함께 작동하는 파일 업로드 및 검색 시스템을 얻는 가장 빠르고 가장 기본적인 방법을 보여줍니다. 궁극적으로 여러 파일 업로드, 고급 오류 처리, 진행 표시기, URL을 데이터베이스에 저장, 파일 선택 및 파일 업로드의 별도 프로세스와 같은 고급 기능을 추가하고 싶을 것입니다. 그러나 데모는 시작하기에 충분해야 합니다. 앱에서 파일 업로드 기능으로 수행할 수 있는 작업이 많으므로 이 데모가 시작하는 데 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기