代码之家  ›  专栏  ›  技术社区  ›  Piyush Patel

如何使用javascript fetch api和express multer上传图像

  •  5
  • Piyush Patel  · 技术社区  · 7 年前

    我在一个reactjs应用程序中工作,在那里我必须上传用户图像。我正在获取文件输入的onChange事件上的文件,并将其传递给父组件,父组件将使用数据发出post请求

    服务器端我使用express和multer进行文件上传,客户端使用fetch api上传图像。

    提前感谢:)

    1 回复  |  直到 7 年前
        1
  •  4
  •   Piyush Patel    7 年前

    我想出来了 要将文件/图像上载到multer,我们需要一个表单enctype=“多部分/表单数据”,否则它将无法与multer一起工作

    我正在从子组件获取文件 1) 我用encType=“多部分/表单数据”创建了一个空表单 2) 当我收到文件时,我创建了一个新的FormData(引用myform) 3) 然后在formData中追加键和值 4) 创建提取。post(),它可以工作:)

    参考提交代码

    反应父组件上载。js公司

    import React, { Component } from 'react'
    
    import { ImageWithoutForm } from "../app/components/ImageUpload";
    
    
    export default class UploadFile extends Component {
        onImageLoad(e){
            console.log('onImageLoad', e.target.files[0]);
            this.uploadForm(e.target.files[0]);
        }
    
        uploadForm(file){
            let form = new FormData(this.refs.myForm);
            form.append('myImage', file);
            fetch('/upload-image', {
              method: 'POST',
              body: form
            }).then(res => console.log('res of fetch', res));
        }
    
      render() {
        return (
          <div>
            <h4>Upload Image</h4>
            <ImageWithoutForm onImageLoad={(e)=>this.onImageLoad(e)} />
            <form id="upload_form" ref="myForm"  encType="multipart/form-data">
            </form>
          </div>
        )
      }
    }
    

    使用输入对子组件进行反应,以加载文件ImageWithoutForm。js公司

    import React, { Component } from 'react'
    
    export  class ImageWithoutForm extends Component {
    
        handleSubmit(e){
            this.props.onImageLoad(e);
        }
    
    
      render() {
        return (
          <div>
                <input type="file" onChange={(e)=>this.handleSubmit(e)}/>
          </div>
        )
      }
    }
    

    Express Route文件取自某人的github repo和自定义上传图像。js公司

    const express = require('express');
    const multer = require('multer');
    const path = require('path');
    
    // Set Storage Engine
    const storage = multer.diskStorage({
      destination: './public/uploads/',
      filename: function(req, file, cb){
        cb(null,file.fieldname + '-' + Date.now() + path.extname(file.originalname));
      }
    });
    
    // Init Upload
    const upload = multer({
      storage: storage,
      limits:{fileSize: 1000000},
      fileFilter: function(req, file, cb){
        checkFileType(file, cb);
      }
    }).single('myImage');
    
    // Check File Type
    function checkFileType(file, cb){
      // Allowed ext
      const filetypes = /jpeg|jpg|png|gif/;
      // Check ext
      const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
      // Check mime
      const mimetype = filetypes.test(file.mimetype);
    
      if(mimetype && extname){
        return cb(null,true);
      } else {
        cb('Error: Images Only!');
      }
    }
    
    // Init app
    const app = express.Router();
    
    
    // Public Folder
    app.use(express.static('./public'));
    
    
    app.post('/', (req, res) => {
        console.log('handling upload image');
      upload(req, res, (err) => {
        if(err){
          console.log('first err', err);
          res.send({
            msg: err
          });
        } else {
          if(req.file == undefined){
            console.log('Error: No File Selected!')
            res.send({
              msg: 'Error: No File Selected!'
            });
          } else {
            console.log('File Uploaded!')
            res.send({
              msg: 'File Uploaded!',
              file: `uploads/${req.file.filename}`
            });
          }
        }
      });
    });
    
    module.exports = app;
    

    在我的express应用程序中。js只需要路由文件ImageUpload。js公司

    然后像这样绘制路线图

    var uploadImage = require('./routes/UploadImage');
    server.use('/upload-image', uploadImage);