TypeError:尝试上传图像时无法读取未定义的属性“路径”
Posted
技术标签:
【中文标题】TypeError:尝试上传图像时无法读取未定义的属性“路径”【英文标题】:TypeError: Cannot read property 'path' of undefined when trying to upload image 【发布时间】:2021-07-11 22:40:08 【问题描述】:。这个错误让我发疯!当我使用 POSTMAN 时,我可以毫无问题地上传图像,但是当我通过网络应用程序上传图像时,我得到了上面的错误。我已经对所有内容进行了三次检查,但似乎找不到问题所在。我知道有很多与我已阅读所有主题的相同主题的问题,但没有找到解决我问题的单一解决方案。
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;
);
【问题讨论】:
【参考方案1】:试试这个:
-
更改您的
onChangeFile
:
const onChangeFile = e =>
const formData= new FormData();
formData.append('propertyImage', e.target.files[0]);
setPropertyImage(formData)
-
将电话改为
PropertyService
:
PropertyService.postProperty(property).then(data =>
-
把
body
改成postProperty
改成PropertyService
不要拿JSON.stringify()
:
body : property,
-
在
useState()
中取消注释propertyImage
【讨论】:
我将在哪里实现这个,因为我已经尝试了一些事情,但仍然得到错误。是不是所有的字段都需要用formData处理? 您可以创建一个变量来存储所选文件event.target.files[0]
。在调用 beckend 之前,您可以像上面的 sn-p 一样创建 formData
,然后将其发送到 beckend:PropertyService.postProperty(property, formData).then(data =>
。而且不是所有的字段都需要用fromData
处理,只有文件。
我现在有一个新错误,它不会让我发布任何内容。 "POST localhost:3000/user/property 500 (Internal Server Error) postProperty @ PropertyService.js:27"
您可以用您的更改编辑问题吗?
我已经编辑过了,错误似乎来自 PropertyService 和 OnSubmit 部分以上是关于TypeError:尝试上传图像时无法读取未定义的属性“路径”的主要内容,如果未能解决你的问题,请参考以下文章
ExpressJS:TypeError:无法读取未定义的属性“路径”尝试将文件上传到 cloudinary 并将 url 保存到 mongoDB
TypeError:无法读取 JSONPlaceholder 未定义的属性“url”
TypeError:无法读取未定义的属性“instanceIdentifier”(FirebaseStorage)
Angular TypeError:无法读取未定义的属性“名称”