json - Angular - 将文件上传为 base64

标签 json angular rest file-upload base64

我正在尝试将文件从 Angular 4 应用程序上传到接受 base64 字符串作为文件内容的 JSON API 服务。

所以我要做的是 - 使用 FileReader.readAsDataURL 读取文件,然后当用户确认上传时,我将向 API 创建一个 JSON 请求并发送 base64我之前得到的文件的字符串。

这就是问题开始的地方 - 一旦我对“内容”做了一些事情(记录它,发送它,w/e),请求就会被发送,但是它疯狂 慢,例如2MB 文件需要 20 秒。

我试过:

  • 使用 ArrayBuffer 并手动将其转换为 base64
  • 将 base64 字符串存储在 HTML 中并稍后检索
  • 在用户点击上传按钮后读取文件
  • 使用来自 @angular/common 的旧客户端
  • 使用纯 XHR 请求

但一切都会导致相同的结果。

我知道问题出在哪里了。但是为什么会这样?它是浏览器特定的还是 Angular 特定的?是否有更优选的方法(请记住它必须是 base64 字符串)?


注意事项:

  • 更改 API 中的任何内容都超出了我的控制范围
  • API 没问题,通过 postman 发送任何文件都会立即完成

代码:

此方法在用户将文件添加到拖放区时运行:

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)
}

最佳答案

要将大文件发送到服务器,您应该使用 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);
    
}

另外不要忘记设置 header 'Content-Type': undefined,我已经为此绞尽脑汁好几个小时了。

关于json - Angular - 将文件上传为 base64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47603416/

相关文章:

c# - 将 Amazon SNS 与 ServiceStack 集成

json - 在 Common Lisp 中访问嵌套的 JSON 字段

node.js - Express.js 继续以文本形式提供 Angular2 index.html

改变位置时的 Angular 动画元素?

angular - 在 Angular 2 应用程序开始使用 AoT 之前从数据库加载配置

java - 如何在 Spring Controller 中自动将 JSON 映射到 Java 类

.Net & WCF - 如何创建 REST 而不是 SOAP?

javascript - 通过 json 模式 Sequelize 定义模型

java - Spring Boot Rest Api 在 N 个并行保存请求后卡住了

sql - 如何将多列分组为单个数组或类似数组?