Загрузка нескольких файлов в стек MERN - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь реализовать функцию загрузки файлов, используя multipart, чтобы ускорить загрузку при большом размере файла.

Я не могу понять, почему это не работает.

Я предоставляю средупеременные через консоль на данный момент.

Когда я нажимаю кнопку отправки, ничего не происходит.Оба моих сервера работают нормально (я в них совершенно уверен)

Проблема:

1>, когда я

axios.post(`http://localhost:4000`, data) 

выдает ошибку.Как мне опубликовать свой файл (данные) в бэкэнде?

Пожалуйста, укажите на ошибки или вещи, которые нужно сделать.

Заранее спасибо!

Ниже следуетmy FileUpload.js

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

class FileUpload extends Component {

  constructor (props) {

   super(props);

    this.submitFile = this.submitFile.bind(this);

    this.fileInput = React.createRef();
  }


  submitFile = (event) => {

    event.preventDefault();
    var data = {

      file: this.fileInput.current.files[0],
      name: this.fileInput.current.files[0].name
    };

    axios.post(`http://localhost:4000`, data)

    .then(response => {
      console.log(response);
    })

    .catch(error => {
      console.log(error);
    });
  }

  render() {

    return (

      <form onSubmit={this.submitFile}>
        <input type='file' ref={this.fileInput} />

        <button type='submit'>Send</button>
      </form>

    );
  }

}

 export default FileUpload;

Мой бэкэнд-узел upload.js выглядит следующим образом:

const multer = require('multer');
const multerS3 = require('multer-s3');
const AWS = require('aws-sdk');

var cred = require('../aws/config')

const AWS_SECRET_ACCESS = cred.access();
const AWS_ACCESS_KEY = cred.awskey();


// configure the keys for accessing AWS
AWS.config.update({
  accessKeyId: process.env.AWS_SECRET_ACCESS,
  secretAccessKey: process.env.AWS_ACCESS_KEY,
  region: ''
});

// create S3 instance
const s3 = new AWS.S3();

const upload = multer({
  storage: multerS3({
    s3:s3,
    bucket: '',
    metadata: function (req, file, cb) {
  cb(null, {fileName: 'uploadit'});
    },
    key: function (req, file, cb) {
      cb(null, Date.now().toString())
    }
  })
})


module.exports = upload;

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Видимо, вы делаете почти все правильно, за исключением одной маленькой детали, которая привлекла мое внимание.

  1. ваш fileName определен из files.name, то есть undefined (попробуйтеconsole.log, что проверить).Что вам нужно сделать, это дать ему уникальное имя, например, отметку времени.
app.post('/upload', (request, response) => {
  const form = new multiparty.Form();
    form.parse(request, async (error, fields, files) => {
      if (error) throw new Error(error);
      try {
        const path = files.file[0].path;
        const buffer = fs.readFileSync(path);
        const type = fileType(buffer);
        const fileName = Date.now().toString();
        const data = await uploadFile(buffer, fileName, type);
        return response.status(200).send(data);
      } 

      catch (error) {
        return response.status(400).send(error);
      }
    });
});

Также убедитесь, что вы перенаправляете свои запросы: https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development

Некоторыедополнительные приемы отладки, если вы еще не пробовали:

  • Попробуйте создать простой маршрут get на вашем сервере, просто чтобы убедиться, что клиент и сервер общаются друг с другом.
  • Попробуйте сначала создать запрос get для перечисления ваших сегментов, чтобы убедиться, что связь с S3 работает должным образом: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#listBuckets-property

Надеюсь, это поможет!Ура!

0 голосов
/ 05 февраля 2019

Я всегда загружаю свои фото на облачный.Вы также можете сохранить их локально, но в долгосрочной перспективе я не думаю, что это решение.

Backend

import express from 'express'; 
import webpackMiddleware from 'webpack-dev-middleware';
import webpack from 'webpack';
import webpackConfig from './webpack.config.js';
const app = express();
app.use(webpackMiddleware(webpack(webpackConfig)));
const port = process.env.PORT || 5000;
const cloudinary = require('cloudinary');

cloudinary.config({ 
  cloud_name: 'your cloud name', 
  api_key: 'your api key', 
  api_secret: 'your api secret' 
});

app.use(multipartMiddleware);
app.post('/images', multipartMiddleware, (req, res) => {
  // file upload
  let formData = Object.values(req.files);
  let photoName = Object.keys(req.files);

  cloudinary.uploader.upload(
    formData[0].path,
    function () { res.json('Uploaded!')},
    {
      public_id: photoName[0],
      crop: 'scale',
      width: 1200,
      height: 400,
      quality: 100,
      tags: ['usedCars', 'usedCars']
    }
  )
});
app.listen(port, () => {
  console.log('Your app on port:', port);
});

Frontend

  // input type file
  <input type="file"
   accept="image/*"
   onChange={evt => this.updateFileValue(evt)}
   id="carPhoto"/>

  // updating state
  updateFileValue(evt) {
    this.setState({
       carPhoto: evt.target.files[0]
    });
  }

  // post request
  Apis.addCarsList(this.state).then((res) => {
    const fd = new FormData();
    const photoName = "a name for your photo, I usually get  the mongoId as a photo name";
    fd.append(res.data, this.state.carPhoto, photoName);
    axios.post('/images', fd).then((res) => {
      // do w/e
    });
  })
...