Axios POST 无法识别从 react

时间:2021-06-10 14:35:48

标签: node.js reactjs express axios

我已经在后端使用 nodejs 制作了一个宁静的 API,这是我的文件夹结构:

├── server
│   ├── project.controller.js
│   ├── auth.js
│   └── project.routes.js
│   └── project.model.js
├── client
│   └── AddProjectModal.js
│   └── axios.service.js
│   └── auth-header.js

服务器 api 似乎工作正常,因为我可以使用邮递员执行 CRUD 操作,但是如果我尝试从响应的客户端发送 post 请求,我不知何故无法继续。我尝试使用 console.log 自我调试数小时以找出我做错的地方,但我找不到任何东西。

这是我的 AddProjectModal.js:

import React, { useState } from "react";
import { authAxios } from "../../services/axios.service";

const AddProjectModal = ({ isShow, isClose }) => {
  const [newProject, setNewProject] = useState({
    title: "",
    type: "",
    description: "",
    //thumbnail: "",
  });

  const handleUpload = async (e) => {
    e.preventDefault();
    var formData = new FormData();
    formData.append("title", newProject.title);
    formData.append("type", newProject.type);
    formData.append("description", newProject.description);
    // formData.append("thumbnail", newProject.thumbnail);
    console.log(...formData);
    try {
      await authAxios
        .post("/api/project/", formData)
        .then((res) => {
          console.log(res.data);
        })
        .catch((e) => {
          console.log(e);
        });
    } catch (err) {
      console.log(err);
    }
  };

.... 
}

如您所见,我尝试使用 console.log(...formData) 查看数据是否已成功附加,结果确实如此。这是示例结果:

result from console.log(...formData)

这是我的 axios.service.js 代码:

import axios from "axios";
import authHeader from "./auth-header";

const apiUrl = "http://localhost:5000/";

export const authAxios = axios.create({
  baseURL: apiUrl,
  headers: authHeader(),
});

export const publicAxios = axios.create({
  baseURL: apiUrl,
});

我的 auth-header.js 代码:

const authHeader = () => {
  const user = JSON.parse(localStorage.getItem("user"));

  if (user && user.accessToken) {
    return { "x-access-token": user.accessToken };
  } else {
    return {};
  }
};

export default authHeader;

还有我的后端代码:

project.routes.js :

const express = require("express");
const router = express.Router();

const auth = require("../../middleware/auth");
const controller = require("../../controllers/project.controller");

//Upload new project
router.post("/", auth, controller.createProject);


module.exports = router;

project.controller.js :

const Project = require("../models/project.model");
// create & save new project
exports.createProject = async (req, res, next) => {
  console.log(req.body);
  if (!req.body.title || !req.body.type || !req.body.description) {
    res.status(400).send({ message: "Form cant be empty!" });
    return;
  }

  try {
    //create project
    const project = new Project({
      title: req.body.title,
      type: req.body.type,
      description: req.body.description,
    });
    // save project to the database
    const createdProject = await project.save();
    res.send(createdProject);
  } catch (err) {
    console.log("err" + err);
    res.status(500).send(err);
    next(err);
  }
};

在上面的代码中,我试图通过 console.log(req.body) 查看是否正在传入数据,当我使用邮递员发布请求时,我得到了以下结果: enter image description here

这是我从浏览器请求时的结果,我得到了空对象:

enter image description here

由于我可以从 Postman 发出请求,我认为问题不在我的服务器端,这是我尝试从浏览器发出 post 请求时的结果: enter image description here

3 个答案:

答案 0 :(得分:1)

解释

  • 为什么它适用于 Postman 而不适用于客户端代码?

区别在于请求的格式。在 Postman 中,您将数据作为 JSON 对象发送。在客户端代码中,您在表单数据中发送数据。他们是不同的。这就是 req.body 为空的原因。 不同的请求格式要求服务器以不同的方式解析

行动

我在您的代码中看到 //formData.append("thumbnail", newProject.thumbnail); 行被注释,您准备在请求中发送项目的缩略图。在这种情况下,您无法以 JSON 格式发送请求。您需要修改服务器以使其理解表单数据。

为此,我推荐这个popular package

<块引用>

Multer 是一个用于处理 multipart/form-data 的 node.js 中间件,它 主要用于上传文件。

答案 1 :(得分:0)

我通过使用 react-hook-form 库解决了这个问题。像这样编辑我的 AddProjectModal.js :

import axios from "axios";
import React, { useState } from "react";
import { Button, Modal, Form } from "react-bootstrap";
import { Controller, useForm } from "react-hook-form";

import { authAxios } from "../../services/axios.service";

const AddProjectModal = ({ isShow, isClose }) => {
  const { control, handleSubmit } = useForm({
    defaultValues: {
      title: "",
      type: "",
      description: "",
      thumbnail: "",
    },
  });
  const onSubmit = async (data) => {
    try {
      setLoading(true);
      await authAxios
        .post("/api/project/", data)
        .then((res) => {
          console.log(res.data);
        })
        .catch((e) => {
          console.log(e);
        });
    } catch (err) {
      console.log(err);
    }
  };
  
  return (
    <Modal show={isShow === "modal-one"} onHide={isClose}>
      <Modal.Header>
        <Modal.Title>Tambahkan Project</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <form encType="multipart/form-data">
          <Form.Group controlId="title">
            <Form.Label>Judul Project</Form.Label>
            <Controller
              control={control}
              name="title"
              render={({ field: { onChange, value } }) => (
                <Form.Control
                  type="text"
                  placeholder="Nama Project"
                  onChange={onChange}
                  value={value}
                />
              )}
            />
          </Form.Group>
          <Form.Group controlId="type">
            <Form.Label>Jenis Projek : </Form.Label>
            <Controller
              control={control}
              name="type"
              render={({ field: { onChange, value } }) => (
                <Form.Control as="select" onChange={onChange} value={value}>
                  <option value=""> </option>
                  <option value="web apps">Web Apps</option>
                  <option value="mobile apps">Mobile Apps</option>
                  <option value="landing page">Landing Page</option>
                </Form.Control>
              )}
            />
          </Form.Group>
          <Form.Group controlId="description">
            <Form.Label>Deskripsi Projek</Form.Label>
            <Controller
              control={control}
              name="description"
              render={({ field: { onChange, value } }) => (
                <Form.Control
                  as="textarea"
                  rows={3}
                  value={value}
                  onChange={onChange}
                />
              )}
            />
          </Form.Group>
          <Form.Group>
            <label>Foto Anda</label>
            <Controller
              control={control}
              name="thumbnail"
              render={({ field: { onChange, value } }) => (
                <Form.File
                  type="file"
                  id="thumbnail"
                  onChange={onChange}
                  value={value}
                />
              )}
            />
          </Form.Group>
        </form>
      </Modal.Body>
      <Modal.Footer>
        <Button type="submit" onClick={handleSubmit(onSubmit)}>
          Upload
        </Button>
        <Button onClick={isClose}>Close</Button>
      </Modal.Footer>
    </Modal>
  );
};

export default AddProjectModal;

对我来说问题是我以前的表单不会发送输入的数据。使用 react-hook-form 后,基本上我存储所有传递到 {control} 的数据(因为我使用自定义组件 react- bootstrap ) ,如果您使用普通形式,则可以使用 {register} 代替!

答案 2 :(得分:0)

更新

正如 Dang Khoa 所说,他建议安装 multer 来处理表单数据类型。如果您不想使用 react-hooks-form ,您仍然可以通过安装 multer 并在您的服务器上编辑 index.js / app.js 以包含 multer 来处理表单数据类型:

const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors"); // this
const multer = require("multer");
require("dotenv").config();

const app = express();
const upload = multer();

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());
app.use(upload.array()); // and this
//cors

相关问题