Node.js TypeError:无法读取属性';路径';尝试上载图像时的未定义值

Node.js TypeError:无法读取属性';路径';尝试上载图像时的未定义值,node.js,reactjs,express,multer,cloudinary,Node.js,Reactjs,Express,Multer,Cloudinary,TypeError:尝试上载图像时无法读取未定义的属性“path”。这个错误快把我逼疯了!当我使用POSTMAN时,我可以上传没有问题的图像,但是当我通过web应用程序上传图像时,我会遇到上面的错误。我把所有东西都检查了三遍,似乎找不到问题。我知道有很多问题都是关于同一个主题的,我都读过了,却没有找到一个解决问题的方法 BACKEND==================================================================================

TypeError:尝试上载图像时无法读取未定义的属性“path”。这个错误快把我逼疯了!当我使用POSTMAN时,我可以上传没有问题的图像,但是当我通过web应用程序上传图像时,我会遇到上面的错误。我把所有东西都检查了三遍,似乎找不到问题。我知道有很多问题都是关于同一个主题的,我都读过了,却没有找到一个解决问题的方法

BACKEND======================================================================================
userRouter.post('/property', parser.single('propertyImage'),passport.authenticate('jwt',{session : false}),(req,res)=>{
    console.log(req.file);
//    const result =  cloudinary.uploader.upload(
//     req.file.path)
//     console.log(result)
    
    const property = new Property({
        street: req.body.street,
        town: req.body.town,
        area: req.body.area,
        PostCode: req.body.PostCode,
        NoBeds: req.body.NoBeds,
        NoBath: req.body.NoBath,
        NoLivingRooms: req.body.NoLivingRooms,
        askingPrice: req.body.askingPrice,
        propertyImage: req.file.path
        
    });

     property.save(err=> {
        if(err)
         res.status(500).json({message : {msgBody: "Error has occured", msgError : true}});
        else{
            req.user.properties.push(property);
            
            req.user.save(err=> {
                if(err)
                 res.status(500).json({message : {msgBody: "Error has occured", msgError : true}});
                 else
                
                 res.status(200).json({message: {msgBody: "Successfully created property", msgError : false}});
            })
        }
    })
});

MULTER AND CLOUDINARY SETTINGS=====================================================
const cloudinary = require("cloudinary").v2;


cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
});

module.exports = cloudinary;

const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
const express = require('express');
const multer = require('multer');
 
const app = express();
 
const storage = new CloudinaryStorage({
  cloudinary: cloudinary,
  params: {
    folder: 'propertyImages',
    format: async (req, file) => 'png', // supports promises as well
    public_id: (req, file) => 'computed-filename-using-request',
  },
});
 parser = multer({ storage: storage });

module.exports = parser
 


FRONTEND===============================================================================
 import React, {useState,useContext} from 'react'
import PropertyItem from './PropertyItem';
import PropertyService from '../Services/PropertyService';
import Message from './Message'
import {AuthContext} from '../Context/AuthContext';
import '../stylesheets/Property.css'

const Properties = props =>{
    const [property,setProperty] = useState({
        // propertyImage: "",
        street : "",
        town : "",
        area : "",
        PostCode : "",
        NoBeds : "",
        NoBath : "",
        NoLivingRooms : "",
        askingPrice: "",
    })
    const [propertyImage,setPropertyImage] = useState ([]);
    const [message,setMessage] = useState(null);
    const authContext = useContext(AuthContext);

    const onSubmit = e =>{
        e.preventDefault();
        
        const formData= new FormData();
        formData.append('propertyImage', propertyImage);
                    PropertyService.postProperty(property, formData).then(data =>{
            const {message } = data;
            resetForm();
            if(message.msgBody === "UnAuthorized"){
                setMessage(message);
                authContext.setUser({username : ""});
                authContext.setIsAuthenticated(false);
            }
            else{
                setMessage(message);
            }
        },[]);
    }

    const onChange = e =>{
        setProperty({...property,[e.target.name] : e.target.value})
    }
    const onChangeFile = e =>{
         setPropertyImage(e.target.files[0])
    }

    
    

    const resetForm = ()=>{
        setProperty({
        propertyImage: "",
        street : "",
        town : "",
        area : "",
        PostCode : "",
        NoBeds : "",
        NoBath : "",
        NoLivingRooms : "",
        askingPrice : "",
        })

    }


    
    return(
        <div>
            <div className="login-container-p">
            <form onSubmit={onSubmit} encType="multipart/form-data" className='login-box-p'>
            <div className="a">
                <label htmlFor="street" className="screen-name-p">Street Name</label>
                <input type="text" 
                       name="street" 
                       value={property.street}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="street name"/>
                <label htmlFor="town" className="screen-name-p">Town</label>
                <input type="text" 
                       name="town" 
                       value={property.town}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="town"/>
                <label htmlFor="area" className="screen-name-p">Area</label>
                <input type="text" 
                       name="area" 
                       value={property.area}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="area"/>
                <label htmlFor="postcode" className="screen-name-p">Postcode</label>
                <input type="text" 
                       name="PostCode" 
                       value={property.PostCode}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="Postcode"/>
            </div>
            <div className="b">
                <label htmlFor="NoBeds" className="screen-name-p">Beds</label>
                <input type="number" 
                       name="NoBeds" 
                       value={property.NoBeds}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="Number of beds"/>
                <label htmlFor="NoBath" className="screen-name-p">Bathrooms</label>
                <input type="number" 
                       name="NoBath" 
                       value={property.NoBath}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="Number of bathrooms"/>
                <label htmlFor="NoLivingRooms" className="screen-name-p">Living Rroom</label>
                <input type="number" 
                       name="NoLivingRooms" 
                       value={property.NoLivingRooms}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="Number of living rooms"/>
                <label htmlFor="askingPrice" className="screen-name-p">Asking Price(£)</label>
                <input type="text" 
                       name="askingPrice" 
                       value={property.askingPrice}
                       onChange={onChange}
                       className="form-control-p"
                       placeholder="£249,999"/>
                <label htmlFor="propertyImage" className="screen-name-p">Property Images</label>
                <input type="file" 
                       id="file"
                       filename="propertyImage" 
                       name="propertyImage"
                       onChange={onChangeFile}
                       className="form-control-p"
                       placeholder="Upload property images"/>
            </div>
            <div className="c">
                <button className="" 
                        type="submit">Submit</button>
            </div>
                
            </form>
            {message ? <Message message={message}/> : null}
            </div>
        </div>
    );

}


export default Properties
PropertyService.js==================================================
export default {
    getProperties : ()=>{
        return fetch('/user/properties')
                .then(response=>{
                    if(response.status !== 401){
                        return response.json().then(data => data);
                    }
                    else
                        return {message : {msgBody : "UnAuthorized",msgError : true}};
                },[]);
    },

    getAllProperties : ()=>{
        return fetch('/properties')
                .then(response=>{
                    if(response.status !== 202){
                        return response.json().then(data => data);
                    }
                    else
                        return {message : {msgBody : "Error",msgError : true}};
                },[]);
    },
  

    
    postProperty : property=>{
        return fetch('/user/property', {
            method : "post",
            body : JSON.stringify(property),
            headers:{
                'Content-Type' : 'application/json'
            }
        }).then(response=>{
            if(response.status !== 401){
                return response.json().then(data => data);
            }
            else
                return {message : {msgBody : "UnAuthorized"},msgError : true};
        });
    }
}
后端======================================================================================
userRouter.post('/property',parser.single('propertyImage'),passport.authenticate('jwt',{session:false}),(req,res)=>{
console.log(请求文件);
//const result=cloudinary.uploader.upload(
//req.file.path)
//console.log(结果)
const属性=新属性({
街道:req.body.street,
城镇:req.body.town,
区域:要求的主体区域,
邮政编码:req.body.PostCode,
NoBeds:req.body.NoBeds,
NoBath:req.body.NoBath,
无起居室:要求主体无起居室,
askingPrice:req.body.askingPrice,
propertyImage:req.file.path
});
属性。保存(错误=>{
如果(错误)
json({message:{msgBody:“发生错误”,msgError:true}});
否则{
请求用户属性推送(属性);
请求用户保存(错误=>{
如果(错误)
json({message:{msgBody:“发生错误”,msgError:true}});
其他的
json({message:{msgBody:“已成功创建属性”,msgError:false}});
})
}
})
});
MULTER和CLOUDINARY设置=====================================================
const cloudinary=require(“cloudinary”).v2;
cloudinary.config({
cloud\u name:process.env.cloud\u name,
api_键:process.env.api_键,
api_secret:process.env.api_secret,
});
module.exports=cloudinary;
const cloudinary=require('cloudinary').v2;
const{CloudinaryStorage}=require('multer-storage-cloudinary');
const express=require('express');
const multer=require('multer');
常量app=express();
const storage=新的CloudinaryStorage({
cloudinary:cloudinary,
参数:{
文件夹:“PropertyImage”,
格式:async(req,file)=>png',//也支持承诺
public_id:(请求,文件)=>“使用请求计算的文件名”,
},
});
parser=multer({storage:storage});
module.exports=解析器
前端===============================================================================
从“React”导入React,{useState,useContext}
从“./PropertyItem”导入PropertyItem;
从“../Services/PropertyService”导入PropertyService;
从“./Message”导入消息
从“../Context/AuthContext”导入{AuthContext};
导入“../stylesheets/Property.css”
常量属性=道具=>{
const[property,setProperty]=useState({
//属性图像:“”,
街道:“,
镇:“,
面积:“,
邮政编码:“,
贵族:“,
NoBath:“,
无起居室:“,
询问价格:“,
})
常量[propertyImage,setPropertyImage]=useState([]);
const[message,setMessage]=useState(null);
const authContext=useContext(authContext);
const onSubmit=e=>{
e、 预防默认值();
const formData=new formData();
formData.append('propertyImage',propertyImage);
postProperty(属性,formData)。然后(数据=>{
const{message}=数据;
resetForm();
如果(message.msgBody==“未经授权”){
设置消息(消息);
authContext.setUser({username:});
authContext.setIsAuthenticated(false);
}
否则{
设置消息(消息);
}
},[]);
}
const onChange=e=>{
setProperty({…属性,[e.target.name]:e.target.value})
}
const onChangeFile=e=>{
setPropertyImage(e.target.files[0])
}
常量重置形式=()=>{
setProperty({
属性图像:“”,
街道:“,
镇:“,
面积:“,
邮政编码:“,
贵族:“,
NoBath:“,
无起居室:“,
询问价格:“,
})
}
返回(
街道名称
城镇
地区
邮政编码
床
浴室
活生生的罗姆
要价(英镑)
属性图像
提交
{消息?:null}
);
}
导出默认属性
PropertyService.js==================================================
导出默认值{
getProperties:()=>{
返回fetch(“/user/properties”)
。然后(响应=>{
如果(response.status!==401){
返回response.json().then(data=>data);
}
其他的
返回{message:{msgBody:“UnAuthorized”,msgError:true};
},[]);
},
getAllProperties:()=>{
返回fetch(“/properties”)
。然后(响应=>{
如果(response.status!==202){
返回response.json().then(data=>data);
}
其他的
返回{message:{msgBody:“Error”,msgError:true};
const onChangeFile = e =>{
   const formData= new FormData();
   formData.append('propertyImage', e.target.files[0]);
   setPropertyImage(formData)
}
PropertyService.postProperty(property).then(data =>{
body : property,