我正在使用express和busboy上传文件(从Angular应用程序中)。
如果正在上传大文件并且检测到错误-例如“文件路径不存在”,则响应客户端的唯一方法是等待完整的文件上传流完成-即使没有任何响应发生在文件中。
在busboy.on('file', async (...) => { ... })
事件函数中使用busboy,如果遇到错误,我将使用以下代码来答复客户端:
const result = await doStuffWithFileStream(file).catch( error => {
fileUploadErrors.push(error);
});
if (fileUploadErrors.length > 0) {
res.json({ success: false, errors: fileUploadErrors });
}
如果上传的文件很大,我会得到以下(错误的)客户端HttpErrorResponse
:
{
"headers": {
"normalizedNames": {
},
"lazyUpdate": null,
"headers": {
}
},
"status": 0,
"statusText": "Unknown Error",
"url": "http:\/\/192.168.0.128:4500\/api\/project\/5d4c1e3375895a00310746dd\/upload\/qcgrnwut-igivxoqa-rqqphqhx",
"ok": false,
"name": "HttpErrorResponse",
"message": "Http failure response for http:\/\/192.168.0.128:4500\/api\/project\/5d4c1e3375895a00310746dd\/upload\/qcgrnwut-igivxoqa-rqqphqhx: 0 Unknown Error",
"error": {
"isTrusted": true
}
}
但是,如果我修改busboy.on('file', async (...) => { ... })
函数并添加以下内容,以通读文件流:
file.on('data', (data) => {
console.log(data);
});
文件上传流(尽管没有到达任何地方)完成,并且以下HttpResponse
发送到客户端( 完成后):
{
"headers": {
"normalizedNames": {
},
"lazyUpdate": null
},
"status": 200,
"statusText": "OK",
"url": "http:\/\/192.168.0.128:4500\/api\/project\/5d4c1e3375895a00310746dd\/upload\/qcgrnwut-igivxoqa-rqqphqhx",
"ok": true,
"type": 4,
"body": {
"success": false,
"errors": [
{
"file": "TestVideo.wmv",
"message": "Failed to upload to \/home\/joe\/uploads\/does-not-exist: File path does not exist"
}
]
}
}
从测试看来,如果响应是在上传流完成之前发送的,则客户端不会收到响应,而只是一个错误(可能是由于中断流引起的)。
如果以某种方式读取数据流,则它允许完成上传,因此客户端会收到响应。
但是,等待完整上传完成以响应很早发现的错误是非常不现实的。
如何在仍允许发送响应的同时结束上传流? 我不确定这是不是男孩,快递或有角度的客户问题。
编辑:
在用Postman测试了我的API之后,看到它得到了正确的响应,我现在认为这部分是Angular HttpClient问题。
尽管chrome的“开发工具”网络标签也未显示请求的答复,所以我认为仍然有更好的方法在服务器上进行处理。