如何将图像上传到 Cloudinary - MERN 堆栈
How to upload Image to Cloudinary - MERN Stack
我想向 mongo 数据库添加一些公司详细信息,这些详细信息包括公司徽标。所以我想将图片上传到 Cloudinary,然后将 URL 与其他详细信息一起保存在 Mongo 数据库中。
但我的代码似乎不起作用。当我填写表格并单击提交时,图像会上传到 Cloudinary,但不会保存在数据库中。
存储图片
const [ companyLogo, setCompanyLogo] = useState("");
const [ companyLogoURL, setCompanyLogoURL] = useState("");
提交时执行的函数
const handleCompanySubmit = (evt) => {
evt.preventDefault();
const data = new FormData()
data.append("file", companyLogo)
data.append("upload_preset", "Sprint")
data.append("cloud_name", "sprint-ccp")
fetch("https://api.cloudinary.com/v1_1/sprint-ccp/image/upload",{
method:"post",
body:data
})
.then(res => res.json())
.then(data => {
setCompanyLogoURL(data.url)
})
.catch(err => {
console.log(err)
})
//check for empty fields
if (
isEmpty(companyName) ||
isEmpty(companyAddress) ||
isEmpty(companyRegNumber) ||
isEmpty(companyContactNumber)
) {
setCompanyErrorMsg("Please Fill All The Fields");
}else {
let formData = new FormData();
formData.append('companyName', companyName);
formData.append('companyAddress', companyAddress);
formData.append('companyRegNumber', companyRegNumber);
formData.append('companyContactNumber', companyContactNumber);
formData.append('companyLogo', companyLogoURL);
setCompanyLoading(true);
addCompany(formData)
.then((response) => {
setCompanyLoading(false);
setCompanySuccessMsg(response.data.successMsg)
setCompanyData({
companyName: "",
companyAddress: "",
companyRegNumber: "",
companyContactNumber: ""
});
})
.catch((err) => {
setCompanyLoading(false);
setCompanyErrorMsg(err.response.data.errorMsg)
})
}
};
const handleCompanyLogo = (evt) => {
setCompanyLogo(evt.target.files[0])
};
前端视图
<form className="register-form" onSubmit={handleCompanySubmit} noValidate>
<label className="text-secondary">Company Logo :</label>
<input type="file" className="form-control" onChange={handleCompanyLogo}/>
//remaining input fields
<button className="btn btn-info submitButton" >Submit</button>
</form>
api 用于添加公司
export const addCompany = async (data) => {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const response = await axios.post(
"http://localhost:5000/api/auth/clients/company",
data,
config
);
return response;
};
后端控制器
exports.addNewCompany = async(req,res)=>{
const {
companyName,
companyAddress,
companyRegNumber,
companyContactNumber,
companyLogo
} = req.body;
const company = await Company.findOne({ companyName });
if (company) {
return res.status(400).json({
errorMsg: `${req.body.companyName} already exists`,
});
}
try{
const newCompany = new Company();
newCompany.companyName = companyName;
newCompany.companyAddress = companyAddress;
newCompany.companyRegNumber = companyRegNumber;
newCompany.companyContactNumber = companyContactNumber;
newCompany.companyLogo = companyLogo;
await newCompany.save();
res.json({
successMsg: `${req.body.companyName} Company Added Successfully`
});
} catch (err) {
console.log("clientsController error - Add Company ", err);
res.status(500).json({
errorMsg: "Server Error. Please Try again",
});
}
};
我在控制台中得到的错误是这样的
clientsController 错误 - 添加公司错误:公司验证失败:公司徽标:需要路径 companyLogo
。
在 ValidationError.inspect
(C:\CCP\sd08_2021\Backend\node_modules\mongoose\lib\error\validation.js:47:26)
你能帮帮我吗?
我认为你的错误是由一个更微不足道的问题引起的:
当你用fetch发送POST请求时,实际上并没有等待它完成(这是一个promise),所以if ... else {...}
语句中的代码被执行了在 fetch() 终止之前 !
setCompanyLogoURL(data.url)
还没有被调用,所以 formData.append('companyLogo', companyLogoURL);
设置一个空白字符串而不是调用 Cloudinary API.
返回的值
解决方案是使handleCompanySubmit
异步,并等待fetch()
承诺完成。
我想向 mongo 数据库添加一些公司详细信息,这些详细信息包括公司徽标。所以我想将图片上传到 Cloudinary,然后将 URL 与其他详细信息一起保存在 Mongo 数据库中。
但我的代码似乎不起作用。当我填写表格并单击提交时,图像会上传到 Cloudinary,但不会保存在数据库中。
存储图片
const [ companyLogo, setCompanyLogo] = useState("");
const [ companyLogoURL, setCompanyLogoURL] = useState("");
提交时执行的函数
const handleCompanySubmit = (evt) => {
evt.preventDefault();
const data = new FormData()
data.append("file", companyLogo)
data.append("upload_preset", "Sprint")
data.append("cloud_name", "sprint-ccp")
fetch("https://api.cloudinary.com/v1_1/sprint-ccp/image/upload",{
method:"post",
body:data
})
.then(res => res.json())
.then(data => {
setCompanyLogoURL(data.url)
})
.catch(err => {
console.log(err)
})
//check for empty fields
if (
isEmpty(companyName) ||
isEmpty(companyAddress) ||
isEmpty(companyRegNumber) ||
isEmpty(companyContactNumber)
) {
setCompanyErrorMsg("Please Fill All The Fields");
}else {
let formData = new FormData();
formData.append('companyName', companyName);
formData.append('companyAddress', companyAddress);
formData.append('companyRegNumber', companyRegNumber);
formData.append('companyContactNumber', companyContactNumber);
formData.append('companyLogo', companyLogoURL);
setCompanyLoading(true);
addCompany(formData)
.then((response) => {
setCompanyLoading(false);
setCompanySuccessMsg(response.data.successMsg)
setCompanyData({
companyName: "",
companyAddress: "",
companyRegNumber: "",
companyContactNumber: ""
});
})
.catch((err) => {
setCompanyLoading(false);
setCompanyErrorMsg(err.response.data.errorMsg)
})
}
};
const handleCompanyLogo = (evt) => {
setCompanyLogo(evt.target.files[0])
};
前端视图
<form className="register-form" onSubmit={handleCompanySubmit} noValidate>
<label className="text-secondary">Company Logo :</label>
<input type="file" className="form-control" onChange={handleCompanyLogo}/>
//remaining input fields
<button className="btn btn-info submitButton" >Submit</button>
</form>
api 用于添加公司
export const addCompany = async (data) => {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const response = await axios.post(
"http://localhost:5000/api/auth/clients/company",
data,
config
);
return response;
};
后端控制器
exports.addNewCompany = async(req,res)=>{
const {
companyName,
companyAddress,
companyRegNumber,
companyContactNumber,
companyLogo
} = req.body;
const company = await Company.findOne({ companyName });
if (company) {
return res.status(400).json({
errorMsg: `${req.body.companyName} already exists`,
});
}
try{
const newCompany = new Company();
newCompany.companyName = companyName;
newCompany.companyAddress = companyAddress;
newCompany.companyRegNumber = companyRegNumber;
newCompany.companyContactNumber = companyContactNumber;
newCompany.companyLogo = companyLogo;
await newCompany.save();
res.json({
successMsg: `${req.body.companyName} Company Added Successfully`
});
} catch (err) {
console.log("clientsController error - Add Company ", err);
res.status(500).json({
errorMsg: "Server Error. Please Try again",
});
}
};
我在控制台中得到的错误是这样的
clientsController 错误 - 添加公司错误:公司验证失败:公司徽标:需要路径 companyLogo
。
在 ValidationError.inspect
(C:\CCP\sd08_2021\Backend\node_modules\mongoose\lib\error\validation.js:47:26)
你能帮帮我吗?
我认为你的错误是由一个更微不足道的问题引起的:
当你用fetch发送POST请求时,实际上并没有等待它完成(这是一个promise),所以if ... else {...}
语句中的代码被执行了在 fetch() 终止之前 !
setCompanyLogoURL(data.url)
还没有被调用,所以 formData.append('companyLogo', companyLogoURL);
设置一个空白字符串而不是调用 Cloudinary API.
解决方案是使handleCompanySubmit
异步,并等待fetch()
承诺完成。