Запрос Fetch / POST к серверу: пустой массив при получении данных multipart / form; - PullRequest
0 голосов
/ 02 ноября 2019

Я пытаюсь загрузить изображение (ReactJs) на мой сервер (NodeJs + Express + multerJs) в цифровой океан.

Я использую POST-запрос с данными multipart / form-data;

Я получаюуспешное сообщение от multerJs, но я вижу в журнале на сервере, что файлы: [] имеют пустой массив. И этот Digital Ocean, конечно, не добавил ни одного файла.

Когда я делаю тот же запрос Post с формой без обработки отправки формы, все работает, и массив Files не пуст. Код вышеработает:

<form method="post" enctype="multipart/form-data" action="http://localhost:3004/upload_image_test_4"   >    </form>

React.js на стороне клиента:

export default class Select_size extends React.Component {
on_form_submit = (e) => {
    e.preventDefault();
    const fileInput = this.state.file;
    const formData = new FormData();
    formData.append('file', fileInput);
    const options = {
        method: 'POST',
        body: formData,
        headers: {
            'Access-Control-Allow-Origin': '*',
             Accept: 'application/json',
            'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
        }
    };
    var url =
        this.state.action_link +
        '?url=' +
        this.state.id_user +
        '/' +
        this.state.id_draft +
        '&name=' +
        this.state.name_file;
    fetch(url, options);
};

onChange = (e) => {
    this.setState({ file: e.target.files[0] });
};

 constructor(props) {
    super(props);
    this.state = {
  files: [],
  };
this.onChange = this.onChange.bind(this);
  }
render() {
    return (  
<form onSubmit={this.on_form_submit} enctype="multipart/form-data">
                    <input type="file" name="myImage" onChange={this.onChange} />
                    <button type="submit">Upload</button>
</form>

  )}

}

На стороне сервера (Node.js / ExpressJs / Multer / Digital Ocean):

  const express = require('express');
  const router = express.Router();
  const bodyParser = require('body-parser');
  const aws = require('aws-sdk');
  const spacesEndpoint = new aws.Endpoint('fra1.digitaloceanspaces.com');
  const s3 = new aws.S3({
  endpoint: spacesEndpoint,
  accessKeyId: 'myID',
  secretAccessKey: 'MySecretKey'
  });
  const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: 'bucketName',
    acl: 'public-read',
    key: function(request, file, cb) {
        cb(null, urlBucket + name_image);
        }
   })
   }).array('upload', 1);

  router.post('/upload_image_test_4', function(request, response, next) {
  upload(request, response, function(error) {
    console.log(request, 'the request');
    if (error) {
        console.log(error);
        return response.json(error, 'error');
    }
    console.log('File uploaded successfully.');
    return response.json('success its uploaded to digital ocean');
});

});
module.exports = router;

Если кто-нибудь может мне помочь с этим! (Я уже безумно "гуглил" ,,,) Спасибо !!

Ответы [ 3 ]

0 голосов
/ 03 ноября 2019

Относится к пулу событий в React и асинхронному поведению setState.

Изменение обработчика onChange:

Метод 1:

Поместите файл в переменную и установите его в setState.

onChange = (e) => {

      const uploadFile = e.target.files[0] ;
      this.setState({ file: uploadFile  });
};

Метод 2 с помощью event.persist ():

onChange = (e) => {
         e.persist();
         this.setState({ file: e.target.files[0] });
    };
0 голосов
/ 03 ноября 2019

// РЕДАКТИРОВАТЬ Я нашел решение своего собственного вопроса ... на странице github, посвященной ошибке, связанной с Next.js: Файл не был отправлен назапрос по некоторым причинам. Я использовал Axios таким образом, и теперь он работает:

React-js:

    sendFile = (e) => {
      const data = new FormData();
      const file = e.target.files[0];
      data.append('avatar', file);
     axios
            .post('http://localhost:3004/upload_test_stack_2', data)
            .then(console.log)
          .catch(console.error);  

      }

Сторона сервера (nodeJs):

const upload = multer({
    storage: multerS3({
    s3: s3,
    bucket: 'My Bucket',
    acl: 'public-read',
    key: function(request, file, cb) {


        cb(null, file.originalname);
    }
    })

});

router.post('/upload_test_stack_2', upload.single('avatar'), (req, res) 
 =>      {

    console.log(req.file, 'The file appears here');
    return res.sendStatus(200);
      });
0 голосов
/ 02 ноября 2019

Файлы с ввода - это не массив, а FileArray, попробуйте [... e.target.files] [0]

...