【问题标题】:Angular - upload file as base64Angular - 将文件上传为base64
【发布时间】: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


【解决方案1】:

要将大文件发送到服务器,您应该使用FormData 以便能够将其作为多部分而不是单个大文件发送。

类似:

// import {Http, RequestOptions} from '@angular/http';
uploadFileToUrl(files, uploadUrl): Promise<any> {
  // Note that setting a content-type header
  // for mutlipart forms breaks some built in
  // request parsers like multer in express.
  const options = new RequestOptions();
  const formData = new FormData();

  // Append files to the virtual form.
  for (const file of files) {
    formData.append(file.name, file)
  }
  // Send it.
  return this.http.post(uploadUrl, formData, options);
    
}

另外别忘了设置标题'Content-Type': undefined,我已经为此苦恼了好几个小时。

【讨论】:

  • 这并不能解决我的问题,因为我无法更改 API。我知道这似乎是唯一的解决方案,所以我只是在寻找为什么需要这么多时间来处理请求的答案。还是谢谢
  • 在这种情况下,记住唯一想到的是使用 http 压缩/deflate @realshadow
猜你喜欢
  • 2018-06-21
  • 1970-01-01
  • 2021-05-03
  • 2018-05-05
  • 2016-03-17
  • 2019-10-26
  • 2022-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多