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