我在尝试使用后端的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:无法读取未定义的属性(阅读'文件名')”错误在后端端?如何解决此问题?
1条答案
按热度按时间pqwbnv8z1#
在handleChange函数中,当处理文件输入时,您将使用所选图像的base64数据URL更新formData状态。然后,当调用uploadImage函数时,传递的是formData.image,它是base64字符串,而不是axios和multer期望的实际文件对象。虽然file对象没有存储在formData中,但我认为您应该能够使用e.target.files [0]从文件输入直接访问它。
字符串