所以基本上我创建了一个动物帖子API,它有不同的字段,如名称、类型等,其中之一是我需要上传的照片,我正在使用 multer 和 cloudinary,但它给了我错误“无法读取未定义的属性(读'path')”当我试图弄清楚它时,我发现req.file在animalController.js中未定义
index.js
-------------------------------------------------------------------------------------
import express from 'express';
import * as dotenv from 'dotenv';
import cors from 'cors';
import connectDB from "./mongodb/connect.js";
import userRouter from "./routes/userRoute.js";
import animalRouter from "./routes/animalRoute.js";
dotenv.config();
const app = express();
app.use(cors());
app.use(express.json());
app.use("/api/v1/users", userRouter);
app.use("/api/v1/animals", animalRouter);
const startServer = async () => {
try {
connectDB(process.env.MONGODB_URL);
app.listen(8080, () =>
console.log("Server started on port http://localhost:8080"),
);
} catch (error) {
console.log(error);
}
};
startServer();
---------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
animal.js
---------------------------------------------------------------------------------------
import mongoose from "mongoose";
import {addressSchema} from "./user.js"
const AnimalSchema = new mongoose.Schema({
name: { type: String, required: true, trim :true},
type: {type: String, required:true, trim:true},
description: { type: String, required: true },
bread: {type: String},
age: {type:Number, required: true},
colour: {type:String, required:true},
location: { type: addressSchema, required: true },
date: { type:Date, default: Date.now, required:true },
photo: { type: String, required: true },
adopted: { type:Boolean, default: false, required: true},
creator: { type: mongoose.Schema.Types.ObjectId, ref: "User" }
});
const animalModel = mongoose.model("Animal", AnimalSchema);
export default animalModel;
---------------------------------------------------------------------------
----------------------------------
authMiddleware.js
------------------------------------------------------------------------------------
import jwt from "jsonwebtoken";
import {body} from "express-validator";
import multer from "multer";
//Protected Routes token base
export const fetchUserId = async (req, res, next) => {
try {
const decode = jwt.verify(
req.headers.authorization,
process.env.JWT_SECRET
);
req.user = decode;
next();
} catch (error) {
res.status(401).send({
success: false,
message: error.message,
});
}
};
export const validateRequest = (method) => {
switch (method){
case 'addAnimal': {
return [
body('name','name can not be null').notEmpty(),
body('type','type can not be null').notEmpty(),
body('description','name must be atleast 8 character').isLength({ min: 8 }),
body('age','age must be number').isInt().notEmpty(),
body('colour','colour can not be null').notEmpty(),
body('photo','photo can not be null').notEmpty(),
]
}
case 'updateAnimal' : {
return[
body('description','name must be atleast 8 character').optional().isLength({ min: 8 }),
body('age','age must be number').optional().isInt(),
]
}
}
}
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, file.originalname)
}
})
export const upload = multer({storage:storage});
------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
animalRoute.js
--------------------------------------------------------------------------------------------
import express from "express";
import { addAnimal} from "../controllers/animalController.js";
import { fetchUserId ,validateRequest, upload} from "../middlewares/authMiddleware.js";
const router = express.Router();
//adding animal
router.post("/addAnimal",fetchUserId, upload.single('photo'), validateRequest('addAnimal'), addAnimal);
---------------------------------------------------------------------------------------
------------------------------------------------------
animalController.js
--------------------------------------------------------------------------
import Animal from "../mongodb/models/animal.js";
import User from "../mongodb/models/user.js";
import { v2 as cloudinary } from 'cloudinary';
cloudinary.config({
cloud_name: process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
//post adding animal detail
export const addAnimal = async(req,res) =>{
try {
const {name, type, description, bread, age, colour, location, adopted} = req.body;
console.log(req.file);
const photoUrl = await cloudinary.uploader.upload(req.file.path,(err)=>{
res.status(500).send({
success:false,
message:"error while uploading pic",
error: err.message
});
});
const newAnimal = await Animal.create({name, type, description, bread, age, colour, location, date, photo: photoUrl.url, adopted, creater: req.user._id});
const user = await User.findOne(req.user._id);
user.allAnimal.push(newAnimal._id);
res.status(200).send({ success:true, message: "Animal added successfully" });
} catch (error) {
res.status(500).send({ success:false, message: error.message });
}
};
--------------------------------------------------------
[![here u can see how i am sendinf data](https://i.stack.imgur.com/vyhlZ.png)](https://i.stack.imgur.com/vyhlZ.png)
[![](https://i.stack.imgur.com/ERDyj.png)](https://i.stack.imgur.com/ERDyj.png)
如何上传图片可以,任何人都更正代码。
你是对的,你面临的错误,
"Cannot read properties of undefined (reading 'path')"
,表明 req.file 未定义,这意味着 multer 中间件无法正确处理文件上传。因此,您需要更改当前代码中的一些内容。
在您的
authMiddleware.js
中,您已经为 multer 定义了存储配置。目标应该是目录,而不是原始文件名。更新 multer 存储配置中的目标:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
这样,您应该在项目中创建“uploads”目录。
其次,在您的
animalRoute.js
中,您使用的是upload.single('photo')
,这意味着从客户端发送的FormData中的密钥应命名为“photo”。确保当您从客户端发送数据时,您使用的是正确的图像文件密钥。
而且,随着时间的推移,我意识到注意完整的错误处理很重要。您应该检查
cloudinary.uploader.upload
方法是否返回任何错误。您可以在 await cloudinary.uploader.upload
行周围使用 try-catch 块或使其更简单:
const photoUrl = await cloudinary.uploader.upload(req.file.path, (err, result) => {
if (err) {
console.error("Error uploading photo:", err);
return res.status(500).send({
success: false,
message: "Error while uploading pic",
error: err.message
});
}
return result;
});