Axios 似乎对于文件上传工作得很好,但是,由于它是前端应用程序,我想避免使用第三方库来执行简单的文件上传任务。
我的要求是能够上传文件并获取进度更新,文件大小可能为 1-3GB。
注意,我不能使用
FormData
,因为我最终想使用 S3 presigned urls
,它使用 PUT
并期望原始二进制文件。
除了使用 axios,我遇到了 2 个选择:
虽然使用
fetch
上传似乎很简单,但似乎没有办法获取进度更新。
我遇到的障碍是
https
,它似乎需要一个Readstream
,并且在浏览器中我无法使用fs
模块。所以,只是看到接口,我做了一些像这样的黑客代码(举一个类似的例子,但是,这个使用表单数据):
import https from 'https';
// file = event.target.files[0]
export async function uploadFile(
url: string,
file: File,
onProgress: () => void = noOp,
method = REQ.PUT,
) {
let progressDataLength = 0;
let data = "";
return new Promise((resolve, reject) => {
const req = https.request(
{
hostname: url,
method: method,
headers: {
"Content-Type": file.type,
"Content-Length": file.size,
},
},
function (res) {
res.on("data", (chunk) => {
progressDataLength += chunk.size;
data += chunk;
onProgress();
console.log("Total received: ", `${chunk.size}/${file.size}`);
});
res.on("end", () => {
resolve("Mydata: " + data);
});
},
);
// MY HACKY CODE BIT
const startConversionTime = new Date().getTime();
Readable.from(Buffer.from(await file.arrayBuffer())).pipe(req);
console.log(
"Total conversion time taken: ",
new Date().getTime() - startConversionTime,
);
req.end();
});
}
虽然这个特定的代码产生了下面的错误,但我不确定这是否合法? (转换完成了吗?而且,我真的找不到
File
转换为可读流的示例)
TypeError:“listener”参数必须是 Function 类型。收到类型对象
我有哪些实现此功能的选项以及如何完成?
不幸的是,fetch 本身并不支持上传过程中的进度更新。但是,您可以使用 XMLHttpRequest API,它确实提供进度跟踪。对于上传带有预签名 URL 的大文件并获取进度更新,XMLHttpRequest 更合适。