简体   繁体   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

When I test sending a request containing both image and text grabbbed from user, it comes through to the backend with proper data when I use Postman.当我测试发送包含从用户那里抓取的图像和文本的请求时,当我使用 Postman 时,它会以正确的数据传递到后端。 Not from React front-end, though.不过,不是来自 React 前端。 Request does come through but req.body seems to be empty when I console.log it from backend.请求确实通过了,但是当我从后端 console.log 时, req.body 似乎是空的。 What am I doing wrong?我究竟做错了什么? I am using Multer.我正在使用 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;

your axios request is not right.您的 axios 请求不正确。 axios post request accepts data as a second argument and third argument is for options ( headers etc ), axios post 请求接受数据作为第二个参数,第三个参数用于选项(标头等),

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

another thing is your request is not being triggered at all.另一件事是您的请求根本没有被触发。 try setting input type to submit instead of using the button to trigger onSubmit handler of the form.尝试将输入类型设置为提交,而不是使用按钮来触发表单的 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>

If you are sending form data in the body you need to use the formidable npm module如果您在正文中发送表单数据,则需要使用强大的npm 模块

you can install it using npm i formidable then require formidable at top of the file您可以使用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 **/
    })
})

In addition, I would suggest you use Axios for api calls另外,我建议您使用 Axios 进行 api 调用

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

相关问题 单击按钮如何将数据从React前端发送到Nodejs Express后端 - How to send data from React front-end to Nodejs Express back-end on button click 如何将数据从 React 前端 Hooks 传递到 Express 后端 - How to pass data from React front end Hooks to Express backend 使用 React(前端)从 Express(后端)下载图像 - Download image from Express (Back-end) using React (Front-end) 如何在 react 前端使用 fetch() 从 express 后端获取数据? - How to use fetch() in react front-end to get data from express back-end? PassportJs用户未定义React前端Express / MongoDB后端 - PassportJs User Undefined React Front-end Express/MongoDB Backend 使用 React 前端设置 Express 后端 - Setting up a Express backend with React Front-end 验证Nodejs / Express后端中的输入并将结果发送到React前端 - Validate input in Nodejs/Express back-end and send result to React front-end 如何在前端和后端之间持久化 Firebase Auth state? (Firebase 身份验证 + React + Express) - How to persist the Firebase Auth state between front-end and backend ? (Firebase Auth + React + Express) 使用 React 的文本滑块前端 - Text Sliders front-end using React 无法将数组类型的变量从React.js前端发送到Django后端 - Cannot send an array-type variable from React.js front-end to Django backend
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM