繁体   English   中英

如何使用 Multer 将包含图像和文本的表单输入数据从 React 前端发送到 Express 后端

[英]How to send a form input data containing both image and text from React front-end to Express backend using Multer

当我测试发送包含从用户那里抓取的图像和文本的请求时,当我使用 Postman 时,它会以正确的数据传递到后端。 不过,不是来自 React 前端。 请求确实通过了,但是当我从后端 console.log 时, req.body 似乎是空的。 我究竟做错了什么? 我正在使用 Multer。

//FRONT-END
import React, { useState } from 'react';
import axios from 'axios';

const ListProperty = (props) => {
  const [address, setAddress] = useState('');
  const [file, setFile] = useState(null);
  const [filename, setFilename] = useState('Choose File');

  const handleAddressChange = (evt) => {
    setAddress(evt.target.value);
  };

  const handlePhotoSelect = (evt) => {
    setFile(evt.target.files[0]);
    setFilename(evt.target.files[0].name);
  };

  const handleSubmit = async (evt) => {
    evt.preventDefault();
    const formData = new FormData();
    formData.append('address', address);
    formData.append('upload', file);
    console.log(formData);
    try {
      axios.post('http://localhost:3000/listproperty', {
        headers: { 'Content-Type': 'multipart/form-data' },
        body: formData,
      });
    } catch (err) {
      console.log(err);
    }
  };
  return (
    <div>
      <h2>Property Listing Form</h2>
      <span>Provide property address and Photo</span>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={address}
          onChange={handleAddressChange}
          name={address}
          placeholder="Enter address"
        />
        <br />
        <input type="file" onChange={handlePhotoSelect} />
        <button>Click to list</button>
      </form>
    </div>
  );
};

export default ListProperty;


//BACK-END
const express = require('express');
const PropertyModel = require('../models/propertyModel');
const router = new express.Router();
const UserModel = require('../models/userModel');
const multer = require('multer');

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'public/images');
  },
  filename: function (req, file, cb) {
    const uniqueName = `${Math.random().toString(32).slice(2)}.jpg`;
    req.image = uniqueName;
    cb(null, uniqueName);
  },
});

const upload = multer({ storage });

router.post(
  '/listproperty',
  upload.single('upload'),
  async (req, res) => {
    console.log('hitting Backend router');
    const property = new PropertyModel({
      ...req.body,
      owner: req.user._id,
      photo: req.image,
    });
    await UserModel.findByIdAndUpdate(req.user._id, {
      $push: { properties: property._id },
    });
    try {
      await property.save();
      res.status(200).send(property);
    } catch (err) {
      console.log(err);
      res.status(400).send(err);
    }
  }
);


module.exports = router;

您的 axios 请求不正确。 axios post 请求接受数据作为第二个参数,第三个参数用于选项(标头等),

axios.post('http://localhost:3000/listproperty', formData, {
  headers: { 
    'Content-Type': 'multipart/form-data' 
  }
});

另一件事是您的请求根本没有被触发。 尝试将输入类型设置为提交,而不是使用按钮来触发表单的 onSubmit 处理程序。

<form onSubmit={handleSubmit}>
        <input
            type="text"
            value={address}
            onChange={handleAddressChange}
            name={address}
            placeholder="Enter address"
        />
        <br />
        <input type="file" onChange={handlePhotoSelect} />
        <input type="submit" value="Submit" />
    </form>

如果您在正文中发送表单数据,则需要使用强大的npm 模块

您可以使用npm i formidable安装它,然后在文件顶部要求 formidable

var formidable = require("formidable");
    
router.post(
'/listproperty',
upload.single('upload'),
async (req, res) => {
    
     var form = new formidable.IncomingForm();
      form.multiples = false;
      form.parse(req, async function (err, fields, files) {
    /**now here you can get all files in files and fields with fields
       in your case you have sent
       formData.append('address', address);
       formData.append('upload', file);
       above two data in form
       so you can get your image from files.upload
       and address fields.address **/
    })
})

另外,我建议您使用 Axios 进行 api 调用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM