javascript - 如何使用 Axios 和 React 更新文件
问题描述
我已经用帖子/文章构建了一个 api,现在我正在前端工作。我在为现有帖子上传新照片时遇到问题。我尝试了两种最常用的照片方法,formData 和 JSON Base64。对于这两种方法,我都收到相同的错误响应,Please upload a file, code: 400
. 我不确定我哪里出错了,所以我会提供所有相关文件。
文章.js(服务器)
exports.articlePhotoUpload = asyncHandler(async (req, res, next) => {
const article = await Article.findById(req.params.id);
if (!article) {
return next(
new ErrorResponse(`Article not found with id of ${ req.params.id }`, 404)
);
}
//Make sure user is article owner || make sure user is admin
if (article.user.toString() !== req.user.id || req.user.role !== 'admin') {
return next(
new ErrorResponse(
`User ${ req.user.id } is not authorized to update this article`,
)
)
}
if (!req.files) {
return next(new ErrorResponse(`Please upload a file`, 400))
}
const file = req.files.file;
// Confirm the image is a photo
if (!file.mimetype.startsWith('image')) {
return next(new ErrorResponse(`Please upload an image file`, 400))
}
// Check File Size
if (file.size > process.env.MAX_FILE_UPLOAD) {
return next(
new ErrorResponse(`Please upload an image less than ${ MAX_FILE_UPLOAD }`, 400)
)
}
// Create custom filename
file.name = `photo_${ article._id }${ path.parse(file.name).ext }`;
file.mv(`${ process.env.FILE_UPLOAD_PATH }/${ file.name }`, async err => {
if (err) {
console.log(err);
new ErrorResponse(`Problem with file upload`, 500);
}
await Article.findByIdAndUpdate(req.params.id, { photo: file.name });
res.status(200).json({
success: true,
data: file.name
});
});
});
^上面的函数是服务器端触发错误消息的地方。
axios.js(客户端)
...
axios.defaults.baseURL = 'http://<<ip address>>/api/v1';
axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('auth');
axios.defaults.headers.post['Content-Type'] = 'application/json';
export const uploadPhoto = (id, data) => {
return axios.put(`/articles/${ id }/photo`, {
data
})
}
...
^我觉得我可以更好地格式化这个导出的函数。我可能在这里遗漏了一些东西。
UploadPhoto.jsx(JSON 尝试)
const UploadPhoto = (props) => {
const { register, handleSubmit } = useForm();
const { state } = useStateMachine(updateAction);
const [file, setFile] = useState(null);
const [filename, setFilename] = useState(null);
const onSubmit = async () => {
const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
console.log(reader.result)
});
const data = {
title: filename,
file: await toBase64(file),
}
uploadPhoto(`5ea5e73044718d0b2c2ae5df`, data)
.then(res => console.log(res))
.catch(err => console.log(err.response.data.error))
}
const handleChange = (e) => {
setFile(e.target.files[0]);
setFilename(e.target.files[0].name);
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<h2>Cover Image</h2>
<label>
Select A File:
</label>
<img id="image" src="" alt="" />
<input
type="file"
name="photo"
ref={register}
defaultValue={state.data.photo}
onChange={handleChange}
/>
<label htmlFor="">
Filename
</label>
<input type="submit" />
</form>
)
}
export default withRouter(UploadPhoto);
UploadPhoto.jsx(formData 尝试)
const onSubmit = () => {
const formData = new FormData();
formData.append("file", file);
console.log(file)
uploadPhoto(`5ea5e73044718d0b2c2ae5df`, formData)
.then(res => console.log(res))
.catch(err => console.log(err.response.data.error))
}
这是我第一次构建自己的 api,这就是我将服务器代码放在这里的原因。但是,我 90% 确定我在客户端犯了一个错误,很可能是在 axios.js 文件中。
解决方案
让我们试试这个例子:
const fileUpload = require('express-fileupload');
const app = express();
// enable files upload -- this should also make 'req.files' accessible
app.use(fileUpload({
createParentPath: true
}));
在服务器初始化的开头添加它。之后,您的正常代码应该尝试访问req.files
,因为它现在应该填充文件上传请求。在代码中使用它之前,您需要安装模块 express-fileupload ->npm i express-fileupload
(来源:https ://attacomsian.com/blog/uploading-files-nodejs-express )
推荐阅读
- c# - NJsonSchema C# - 更改生成的值类型
- pca - 如何解释 PCA (fviz_pca_var)?
- aws-iot - 使用策略将 AWS IOT 设备限制为自身
- json - 部分查询匹配的 JPath
- javascript - 如何检查输入字段中的空“//”斜杠
- node.js - MongoDB 在 NodeJS 上找到返回对象的元素
- c++ - 如何在 C++ 中为模板库创建 make 文件?
- git - windows git ssh 连接超时
- amazon-web-services - 如何在 cloudformation 堆栈中为 lambda 配置 asynconfig?
- r - 使用 ifelse 语句从具有相同数据集的数据中创建数据集中的新变量