node.js - 如何将文件/图像从 React 发送到 node.js 服务器

标签 node.js reactjs express postman

我正在尝试使用 multer 将文件/图像从 React 发送到 node.js 服务器。问题是我只能通过 Postman 发送图像,但是当我在 React 中尝试相同的操作时,我得到: TypeError: Cannot read property 'path' of undefined.我不明白是否应该以二进制形式发送文件/图像或使用其他格式。我已经尝试使用 reader.readAsDataURL() 和 reader.readAsBinaryString() 但它不起作用。


const multer = require("multer");

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "./uploads/");
  },
  filename: (req, file, cb) => {
    cb(null, new Date().toISOString() + file.originalname);
  }
});

const fileFilter = (req, file, cb) => {
  if (
    file.mimetype === "image/jpeg" ||
    file.mimetype === "image/png" ||
    file.mimetype === "image/jpg"
  ) {
    cb(null, true);
  }
  cb(null, false);
};

const upload = multer({
  storage: storage,
  limits: { fileSize: 5000000 },
  fileFilter: fileFilter
});

// Create a post
router.post(
  "/",
  upload.single("image"),
  passport.authenticate("jwt", { session: false }),

  (req, res) => {
    const { errors, isValid } = validationPostInput(req.body);
    if (!isValid) {
      return res.status(400).json(errors);
    }
    console.log(req.file);
    const newPost = new Post({
      text: req.body.text,
      theme: req.body.theme,
      name: req.body.name,
      avatar: req.body.avatar,
      image: req.file.path,
      user: req.user.id
    });

    newPost.save().then(post => res.json(post));
  }
);

  // CREATE A POST
export const createPost = (userInput, history) => dispatch => {
  const headers = {
    "Content-Type": "form-data"
  };
  axios
    .post("/post", userInput, headers)
    .then(res => history.push("/post/all"))
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};


   import React, { Component } from "react";
import PropTypes from "prop-types";
// import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { createPost } from "../../actions/postActions";
import "./style.css";

class CreatePost extends Component {
  state = {
    text: "",
    theme: "",
    image: "",
    errors: {}
  };

  componentWillReceiveProps(nextProps) {
    if (nextProps.errors) {
      this.setState({ errors: nextProps.errors });
    }
  }

  onSubmit = e => {
    e.preventDefault();

    const { user } = this.props.auth;

    const newPost = {
      text: this.state.text,
      theme: this.state.theme,
      image: this.state.image,
      name: user.username,
      avatar: user.avatar
    };

    this.props.createPost(newPost);
  };
  onChange = e => this.setState({ [e.target.name]: e.target.value });

  fileSelectHandler = e => {
    const param = e.target.files[0];
    let reader = new FileReader();
    reader.readAsDataURL(param);

    this.setState({
      image: reader.result
    });
    console.log(reader);
  };

  render() {
    const { text, theme, errors } = this.state;

    return (
      <section className="post">
        <form
          onSubmit={this.onSubmit}
          className="post__form"
          action="/post"
          method="POST"
          encType="multipart/form-data"
        >
          <div className="post__form--input">
            <label>Theme</label>
            <input
              type="text"
              name="theme"
              value={theme}
              onChange={this.onChange}
            />
            {errors && <small>{errors.theme}</small>}
          </div>
          <div className="post__form--input">
            <label>Text</label>
            <textarea
              type="text"
              name="text"
              value={text}
              onChange={this.onChange}
            />
            {errors && <small>{errors.text}</small>}
          </div>
          <div className="post__form--file">
            <label>Add Image</label>
            <input
              type="file"
              name="file"
              accept=".png, .jpg"
              onChange={this.fileSelectHandler}
            />
          </div>
          <button type="submit" className="button">
            Submit
          </button>
        </form>
      </section>
    );
  }
}

CreatePost.propTypes = {
  errors: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  errors: state.errors,
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { createPost }
)(CreatePost);

最佳答案

最后,我找到了解决这个问题的方法。

 onSubmit = e => {
    e.preventDefault();

    const { user } = this.props.auth;

    const form = new FormData();
    form.append("file", this.state.file);
    form.append("theme", this.state.theme);
    form.append("text", this.state.text);
    form.append("name", user.username);
    form.append("avatar", user.avatar);

    this.props.createPost(form);
  }

关于node.js - 如何将文件/图像从 React 发送到 node.js 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56709353/

相关文章:

javascript - Mongoose 种群

javascript - 如何在javascript中 trim 末尾不需要的连续字符串?

node.js - 当所需文件不导出任何内容时,require() 会做什么?设置 Mongoose + express 的正确方法是什么?

node.js - 函数返回值在nodejs中未定义

reactjs - 如何强制react-router-v6 路由上存在searchParams?

javascript - ReactJS类型错误: Cannot read property 'eventEmitter' of undefined

reactjs - AEM 中的 React js

javascript - 如何获取 Mongoose 模型中已填充 child 的数量?

javascript - 为什么无法尝试/捕捉某些东西?

node.js - NodeJS/Express 请求实体太大 - Heroku