使用multer在mern堆栈中上传图像不起作用

Image upload in mern stack using multer not working

我正在尝试使用 multer 在 MongoDB 中上传图片并做出反应,但我无法 post 它。我按形式输入了三个输入,即标题、内容和图像。如果我尝试 post 仅标题和内容,它就会成功地被 post 编辑。我还在前端 package.json 文件

中添加了“代理”:“http://localhost:8000”

这是我的表格

function PostCreate() {
  const [title, setTile] = useState("");
  const [content, setContent] = useState("");
  const [image, setImage] = useState({});
  const dispatch = useDispatch();
  const post = useSelector((state) => state.postReducer);

  const fileOnChange = (e) => {
    setImage(e.target.files[0]);
  };
  const submitPost = (e) => {
    e.preventDefault();
    const formData = new FormData();
    formData.append("image", image);
    dispatch(createPost(title, content, image));
  };

  return (
    <div className="postCreate">
      <h3 className="postCreate__heading">Create New Post</h3>
      <div className="formBody">
        <form onSubmit={submitPost}>
          <div className="formInputs">
            <label className="label">Title</label>
            <input
              className="titleInput"
              type="text"
              value={title}
              onChange={(e) => setTile(e.target.value)}
              placeholder="Enter the Title of the Post"
            />
          </div>
          <div className="formInputs">
            <input type="file" onChange={fileOnChange} />
          </div>
          <div className="formInputs">
            <label className="label">Content</label>
            <textarea
              className="titleInput"
              type="text"
              style={{
                width: "1500px",
                height: "500px",
                color: "black",
                outline: "none",
                border: "none",
                borderRadius: "6px",
              }}
              value={content}
              onChange={(e) => setContent(e.target.value)}
            />
          </div>
          <div className="button">
            <Button type="submit" variant="contained" color="primary">
              Post
            </Button>
          </div>

          {/* <button type="submit">Post</button> */}
        </form>

这是我的动作

export const createPost = (title, content, image) => async (dispatch) => {
  try {
    dispatch({ type: POST_POST_LOADING });
    const config = { headers: { "Content-Type": "application/json" } };
    const { data } = await axios.post(
      "/api/newpost",
      { title, content },
      config
    );
    dispatch({
      type: POST_POST_SUCCESS,
      payload: data,
    });
  } catch (error) {
    dispatch({
      type: POST_POST_FAIL,
      payload: error,
    });
  }
};

这是我的post控制器

const createPost = async (req, res) => {
  const { title, content, writer, comment, image } = req.body;
  const fileType = req.file.mimetype.split("/")[1];
  const newFileName = req.file.filename + "." + fileType;
  fs.rename(
    `uploads/images/${req.file.filename}`,
    `uploads/images/${newFileName}`,
    (req, res) => {
      console.log("Renamed");
    }
  );
  // const imageUrl = req.file.filename;
  const newPost = await Post.create({
    title,
    content,
    writer,
    comment,
    image,
    // imageUrl,
  });
  if (newPost) {
    res.send("Post created");
    console.log("Post created");
  } else {
    res.status(201).send("Post not created");
    console.log("Post not created");
  }
};

这是我的路线

router.post("/newpost", upload.single("image"), createPost);

您正在创建一个表单,这是一个好的开始,但没有使用 axios 发送它。

要将文件从前端发送到后端,您需要使用 FormData API 构建一个表单并将文件附加到其中。您还可以向其附加其他数据。

以下是我将如何更改您的代码以使其正常工作。在您的表单文件中:

const formData = new FormData();
formData.append('image', image);
formData.append('title', title);
formData.append('content', content);
dispatch(createPost(formData));

然后将您的操作更改为:

export const createPost = (formData) => async (dispatch) => {
  try {
    dispatch({ type: POST_POST_LOADING });
    const config = { headers: { "Content-Type": "multipart/form-data" } };
    const { data } = await axios.post(
      "/api/newpost",
      formData,
      config
    );
    dispatch({
      type: POST_POST_SUCCESS,
      payload: data,
    });
  } catch (error) {
    dispatch({
      type: POST_POST_FAIL,
      payload: error,
    });
  }
};