NodeJS 使用Multer使用React和Express上传图像时出现错误500

s3fp2yjn  于 2023-08-04  发布在  Node.js
关注(0)|答案(1)|浏览(166)

我在尝试使用后端的Express和Multer作为中间件来管理上传过程时遇到了麻烦。我已经在后端配置了Multer,并在我的React组件中使用Axios将POST请求发送到适当的端点。但是,我一直收到错误500消息,我不知道出了什么问题。
server.js:

import express from "express";
import dotenv from "dotenv";
dotenv.config();
import cors from "cors";
import cookieParser from "cookie-parser";
import corsOptions from "./utils/corsOptions.js";
import multer from "multer";

import authRoute from "./routes/authRoute.js";
import userRoute from "./routes/userRoute.js";
import postRoute from "./routes/postRoute.js";

const port = process.env.APP_PORT || 5000;

const app = express();

app.use(cors(corsOptions));

app.use(express.json());
app.use(cookieParser());

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "../frontend/public/upload");
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + file.originalname);
  },
});

const upload = multer({ storage });

app.post("/api/v1/upload", upload.single("file"), function (req, res) {
  const file = req.file;
  res.status(200).json(file.filename);
});

app.use("/api/v1", authRoute);
app.use("/api/v1", userRoute);
app.use("/api/v1", postRoute);

app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

字符串
ModalEditProfile.jsx:

import { useContext, useState } from "react";
import { AuthContext } from "../../../context/AuthContext";
import PropTypes from "prop-types";
import "./modalEditProfile.scss";
import axios from "axios";

const ModalEditProfile = ({ onClose, onUpdateProfile }) => {
  const { currentUser } = useContext(AuthContext);
  const [formData, setFormData] = useState({
    username: currentUser.username,
    email: currentUser.email,
    image: currentUser.image,
  });

  const handleChange = (e) => {
    const { name, value, type } = e.target;

    // If the input is a file input (for image), handle it separately
    if (type === "file") {
      const file = e.target.files[0];
      const reader = new FileReader();

      reader.onloadend = () => {
        setFormData((prevFormData) => ({
          ...prevFormData,
          image: reader.result, // Update the image value with the base64 data
        }));
      };

      if (file) {
        reader.readAsDataURL(file);
      }
    } else {
      setFormData((prevFormData) => ({
        ...prevFormData,
        [name]: value,
      }));
    }
  };

  const uploadImage = async (imageFile) => {
    try {
      const formDataToSend = new FormData();
      formDataToSend.append("file", imageFile);

      const response = await axios.post(
        "http://localhost:5000/api/v1/upload",
        formDataToSend
      );
      return response.data.imageUrl;
    } catch (error) {
      console.log("Error uploading image:", error);
      return null;
    }
  };

  const handleSubmit = async (e) => {
    e.preventDefault();

    let imageUrl = currentUser.image; // Default image URL, in case no new image is uploaded

    if (formData.image) {
      // Jika ada gambar yang diunggah, upload gambar dan dapatkan URL gambar baru
      imageUrl = await uploadImage(formData.image);
    }

    // Update data profil pengguna dengan URL gambar baru
    const updatedData = { ...formData, image: imageUrl };
    onUpdateProfile(updatedData);
    onClose();
  };

  return (
    <div className="modal">
      <div className="modal-content">
        <h2>Edit Profile</h2>
        <form onSubmit={handleSubmit} encType="multipart/form-data">
          <div className="form-group">
            <label htmlFor="username">Username:</label>
            <input
              type="text"
              id="username"
              name="username"
              value={formData.username}
              onChange={handleChange}
              className="input-field"
            />
          </div>
          <div className="form-group">
            <label htmlFor="email">Email:</label>
            <input
              type="email"
              id="email"
              name="email"
              value={formData.email}
              onChange={handleChange}
              className="input-field"
            />
          </div>
          <div className="form-group">
            <label htmlFor="image">Profile Image:</label>
            <input
              type="file"
              id="image"
              name="image"
              accept="image/*"
              onChange={handleChange}
              className="input-field"
            />
            {formData.image && (
              <img
                src={formData.image}
                alt="Profile"
                className="preview-image"
              />
            )}
          </div>
          {/* Add other fields that can be edited here */}
          <div className="form-actions">
            <button type="submit" className="submit-btn">
              Save Changes
            </button>
            <button type="button" onClick={onClose} className="cancel-btn">
              Cancel
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

ModalEditProfile.propTypes = {
  onClose: PropTypes.func.isRequired,
  onUpdateProfile: PropTypes.func.isRequired,
};

export default ModalEditProfile;


当尝试使用ModalEditProfile组件上传图像时,我在浏览器端收到一个500(内部服务器错误)错误。出现的错误消息为:

ModalEditProfile.jsx:67 POST http://localhost:5000/api/v1/upload 500 (Internal Server Error)
Error uploading image: AxiosError {message: 'Request failed with status code 500', name: 'AxiosError', code: 'ERR_BAD_RESPONSE', ...}


在后端,我看到以下错误消息:

TypeError: Cannot read properties of undefined (reading 'filename')
    at file:///C:/Users/ayub/Documents/latihan/my-blog/backend/src/server.js:35:29
    at Layer.handle [as handle_request] (C:\Users\ayub\Documents\latihan\my-blog\backend\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\ayub\Documents\latihan\my-blog\backend\node_modules\express\lib\router\route.js:144:13)
    at done (C:\Users\ayub\Documents\latihan\my-blog\backend\node_modules\multer\lib\make-middleware.js:45:7)
    at indicateDone (C:\Users\ayub\Documents\latihan\my-blog\backend\node_modules\multer\lib\make-middleware.js:49:68)
    at Multipart.<anonymous> (C:\Users\ayub\Documents\latihan\my-blog\backend\node_modules\multer\lib\make-middleware.js:166:7)
    at Multipart.emit (node:events:513:28)
    at emitCloseNT (node:internal/streams/destroy:132:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:81:21)


我确信后端的Multer配置是正确的,因为我可以毫无问题地从其他组件(例如“写”组件)上传图像。
然而,当我尝试从ModalEditProfile组件上传图像时,我在前端得到一个500错误消息,以及一个**“TypeError:Cannot read properties of undefined(阅读'filename')"**后端错误消息。
我试图找到一个解决办法,但还没有找到正确的答案。谁能帮我检查一下我的代码,告诉我可能出了什么问题?
谢谢你的帮助!
已完成的步骤:我已经检查了后端的multer配置,并确认图像存储目的地已被正确指定。我还验证了写组件使用相同的配置成功地正确上传图像。
问:为什么我在尝试使用ModalEditProfile组件上传图像时收到错误500(内部服务器错误)?什么原因导致“TypeError:无法读取未定义的属性(阅读'文件名')”错误在后端端?如何解决此问题?

pqwbnv8z

pqwbnv8z1#

在handleChange函数中,当处理文件输入时,您将使用所选图像的base64数据URL更新formData状态。然后,当调用uploadImage函数时,传递的是formData.image,它是base64字符串,而不是axios和multer期望的实际文件对象。虽然file对象没有存储在formData中,但我认为您应该能够使用e.target.files [0]从文件输入直接访问它。

const handleSubmit = async (e) => {
   ...
    if (formData.image) {
      imageUrl = await uploadImage(e.target.files[0]);
    }
   ...
}

字符串

相关问题