【发布时间】:2018-05-16 03:37:09
【问题描述】:
我正在尝试将文件从 Angular 4 应用程序上传到 JSON API 服务,该服务接受 base64 字符串作为文件内容。
所以我要做的是 - 使用 FileReader.readAsDataURL 读取文件,然后当用户确认上传时,我将创建一个 JSON 请求到 API 并发送我之前获得的文件的 base64 字符串。
这是问题开始的地方 - 一旦我对“内容”做了一些事情(记录它,发送它,w/e),请求就会被发送,但是它疯狂 慢,例如2MB 文件需要 20 秒。
我试过了:
- 使用
ArrayBuffer并手动将其转换为base64 - 将 base64 字符串存储在 HTML 中并稍后检索
- 用户点击上传按钮后读取文件
- 使用来自
@angular/common的旧客户端 - 使用纯 XHR 请求
但一切都会导致相同的结果。
我知道问题出在哪里。但是为什么会发生?它是特定于浏览器的还是特定于角度的?有没有更首选的方法(请记住它必须是 base64 字符串)?
注意事项:
- 更改 API 中的任何内容都超出我的控制范围
- API 没问题,通过邮递员发送任何文件都会立即完成
代码:
当用户将文件添加到 dropzone 时,此方法运行:
public onFileChange(files: File[]) : void {
files.forEach((file: File, index: number) => {
const reader = new FileReader;
// UploadedFile is just a simple model that contains filename, size, type and later base64 content
this.uploadedFiles[index] = new UploadedFile(file);
//region reader.onprogress
reader.onprogress = (event: ProgressEvent) => {
if (event.lengthComputable) {
this.uploadedFiles[index].updateProgress(
Math.round((event.loaded * 100) / event.total)
);
}
};
//endregion
//region reader.onloadend
reader.onloadend = (event: ProgressEvent) => {
const target: FileReader = <FileReader>event.target;
const content = target.result.split(',')[1];
this.uploadedFiles[index].contentLoaded(content);
};
//endregion
reader.readAsDataURL(file);
});
}
当用户点击保存按钮时该方法运行
public upload(uploadedFiles: UploadedFile[]) : Observable<null> {
const body: object = {
files: uploadedFiles.map((uploadedFile) => {
return {
filename: uploadedFile.name,
// SLOWDOWN HAPPENS HERE
content: uploadedFile.content
};
})
};
return this.http.post('file', body)
}
【问题讨论】:
-
您是在询问您的代码有问题,但您没有发布任何一行代码。
-
@JB Nizet 我添加了相关代码
-
如果您自己使用简单的字符串连接(因为您知道 base64 不包含任何必须编码的字符)而不是让 http 来构建 JSON 字符串,会发生什么?
-
相同的行为。如果我将虚拟数据发送到服务器并尝试 cosole.log 内容,也会发生同样的事情,大约需要 20 秒才能显示在控制台中......
-
2MB 是一个巨大的字符串,要在控制台中显示。
标签: json angular rest file-upload base64