javascript - Busboy 文件事件未触发,在请求正文中接收文件作为缓冲区
问题描述
我正在开发一个使用react-dropzone
钩子实现拖放文件上传功能的反应应用程序。然后我通过 POST 请求将文件发送到 firebase 云功能。
我正在使用 BusBoy 将接收到的文件写入 tmpdir 并将接收到的文件上传到 firebase 存储。
BusBoy 文件事件未在我的云功能中触发。
前端
const onDrop = useCallback((acceptedFiles) => {
// Check whether excel file is uploaded
if (
acceptedFiles[0].type == `application/vnd.ms-excel`.trim() ||
acceptedFiles[0].type ==
`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
`.trim()
) {
auth.currentUser.getIdToken().then((token) => {
let bodyFormData = new FormData();
bodyFormData.append('file', acceptedFiles[0]);
axiosInstance
.post('/upload', bodyFormData, {
crossdomain: true,
headers: {
Authorization: `Bearer ${token.toString()}`,
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS',
},
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
});
} else {
setFileTypeError(true);
}
}, []);
请求标头内容类型为multipart/form-data; boundary=----WebKitFormBoundaryRWo4LrjStmEjoZll
和表单数据是file:{binary}
后端
app.post('/upload', verifyAuth, (req, res) => {
const BusBoy = require('busboy');
const path = require('path');
const os = require('os');
const fs = require('fs');
const busboy = new BusBoy({ headers: req.headers });
let tempFileName;
let fileToBeUploaded = {};
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
console.log('file received');
const fileExtension = filename.split('.')[filename.split('.').length - 1];
tempFileName = `bulk-upload-${shortid.generate()}.${fileExtension}`;
const filePath = path.join(os.tmpdir(), tempFileName);
fileToBeUploaded = { filePath, mimetype };
file.pipe(fs.createWriteStream(filePath));
});
busboy.on('finish', () => {
bucket
.upload(fileToBeUploaded.filePath, {
resumable: false,
metadata: {
metadata: {
contentType: fileToBeUploaded.mimetype,
},
},
})
.then(() => {
return res.status(200).json({ success: true });
})
.catch((err) => {
return res.status(400).json({ error: err });
});
});
});
Busboy On file 事件没有被触发。我还检查了req.file
,这返回未定义。谁能帮助我哪里出错了?
解决方案
我遇到了同样的问题,当我将带有 multipart/form 的文件发送到 express firebase 云函数时,文件事件不会触发。我读了其他帖子,建议删除可以从请求中读取文件流的其他中间件,但这对我不起作用,现在我还没有解决这个问题。
但是,一种可能的替代方法是使用 Firebase API 首先将图片从客户端应用程序直接上传到存储桶,然后执行一些操作(在我的情况下,将记录保存在数据库中):
var photoRef = storage.ref().child(photoName);
var uploadTask = photoRef.put(this.post.photo);
uploadTask.on(
"state_changed",
(snapshot) => {
// Observe state change events such as progress, pause, and resume
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
},
(error) => {
// Handle unsuccessful uploads
},
() => {
// Handle successful uploads on complete
uploadTask.snapshot.ref.getDownloadURL().then((downloadURL) => {
console.log("File available at", downloadURL);
db.collection("images")
.doc(fields.id)
.set({
id: fields.id,
caption: fields.caption,
location: fields.location,
date: parseInt(fields.date),
imageUrl: downloadURL,
})
.then(() => {
console.log("Post added: " + fields.id);
});
});
}
);
如果您需要对服务器上的文件进行处理,您可以先将其上传到存储桶,然后在云功能上检索它。
推荐阅读
- sql - 组合已知查询
- sql-server - 从字符串转换日期和/或时间时转换为日期然后转换失败
- reactjs - 运行 cypress 测试时 axios http 请求中缺少 cookie
- google-colaboratory - 使用pickle加载文件
- azure - AADSTS65001 invalid_grant 当所有权限都得到管理员同意时
- ios - Ionic App 在模拟的 iOS 手机中不起作用
- python - 如何删除重复的解决方案
- python - 尝试将字节解码为字符串时出错
- python - Maya Python:从其他窗口的文本字段中调用名称?
- jupyter - 如何在 jupyter notebook 上停止这些弹出窗口?