req.file 未定义

问题描述 投票:0回答:1

所以基本上我创建了一个动物帖子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)

如何上传图片可以,任何人都更正代码。

node.js mongodb express multer cloudinary
1个回答
0
投票

你是对的,你面临的错误,

"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;
});
© www.soinside.com 2019 - 2024. All rights reserved.