【问题标题】:Form data not always send in Chrome when uploading file with Angular 7使用 Angular 7 上传文件时,表单数据并不总是在 Chrome 中发送
【发布时间】:2019-06-02 09:11:10
【问题描述】:

当我的 Angular 7 应用程序使用 angular-file 上传文件时,表单数据并不总是通过 Chrome (macOS) 发送。我对 Firefox 或 Safari 没有任何问题。刷新 Chrome (F5) 至少在上次发生这种情况时有所帮助。

我将 angular-file 升级到最新版本,但没有帮助。我认为这不是 angular-file 问题,因为我使用 Angular common 的 HttpRequest 进行上传。

Angular 代码如下所示:

  uploadFile(file: File, type: string): Subscription {
    const fileFormData: FormData = new FormData();
    fileFormData.append("file", file, file.name);

    const req = new HttpRequest<FormData>('PUT', '/api/v2/images/' + type, fileFormData, {
      reportProgress: true
    });

    return this.httpEmitter = this.http.request<any>(req)
      .subscribe(
        event => {
          this.appUtil.logHttpEvent(event, file);

          if (event instanceof HttpResponse) {
            this.httpEmitter.unsubscribe();
            this.setImageUrl(type);
          }
        }
      );
  }

  logHttpEvent(event: any, file: File) {
        switch (event.type) {
            case HttpEventType.Sent:
                console.log(`Uploading file "${file.name}" of size ${file.size}.`);
                return;

            case HttpEventType.UploadProgress:
                const percentDone = Math.round(100 * event.loaded / event.total);
                console.log(`File "${file.name}" is ${percentDone}% uploaded.`);
                return;

            case HttpEventType.ResponseHeader:
                console.log(`File "${file.name}" upload got response header ${event.status}/${event.statusText}`);
                return;

            case HttpEventType.DownloadProgress:
                console.log(`File "${file.name}" upload got download progress loaded ${event.loaded} bytes`);
                return;

            case HttpEventType.Response:
                console.log(`File "${file.name}" was completely uploaded!`);
                return;

            default:
                console.log(`File "${file.name}" surprising upload event: ${event.type}.`);
                return;
        }
    }

当上传成功时,它会打印到控制台:

main.23cb89c05a4329fb2f30.js:1 Uploading file "logo.png" of size 6631.
main.23cb89c05a4329fb2f30.js:1 File "logo.png" upload got response header 200/OK
main.23cb89c05a4329fb2f30.js:1 File "logo.png" upload got download progress loaded 1930 bytes
main.23cb89c05a4329fb2f30.js:1 File "logo.png" was completely uploaded!

但是当它失败时会打印:

main.23cb89c05a4329fb2f30.js:1 Uploading file "logo.png" of size 6631.
POST https://www.example.com/api/v2/images/logo 500
main.23cb89c05a4329fb2f30.js:1 File "logo.png" upload got response header 500/OK
main.23cb89c05a4329fb2f30.js:1 File "logo.png" upload got download progress loaded 205 bytes

当我检查网络选项卡时,上传失败时,“请求标头”之后根本没有“表单数据”部分。仍然在请求标头中正确设置了内容类型:“Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2SRIMu3Tb4HzNjJo”

我正在使用 Angular 的默认服务工作者,所以想知道它是否会导致这些问题?

【问题讨论】:

  • 任何更新或解决方案?
  • 8 月 1 日之后我没有收到此错误。我在 8 月 3 日安装了新版本,在那里我升级了许多依赖项,包括 Angular 7.2.12 -> 8.1.1。我不确定是哪个解决了这个问题,但我很高兴它现在工作正常。
  • 我们的问题是由 Service Worker 引起的,并且仅在 Chrome Macos 版本 77 下。解决方案是跳过使用 Service Worker 进行文件上传。
  • 我忘记了,但我们还为上传添加了 ngsw-bypass=true 参数(在 Angular 8 中引入)。
  • 把解决方案变成答案,它可以帮助人们

标签: angular google-chrome


【解决方案1】:

解决方案是将 ngsw-bypass -参数(在 Angular 8 中引入)添加到 url,例如:

const req = new HttpRequest<FormData>('POST', '/api/v2/attachments/orders/' + this.order.id + '?ngsw-bypass=true', fileFormData, {
  reportProgress: true
});

【讨论】:

    【解决方案2】:

    如果您使用的是 @angular/service-worker: 8+,则可以通过在请求中添加 { headers: { 'ngsw-bypass': true } 或查询参数 ngsw-bypass=true 来绕过 Service Worker。

    https://github.com/angular/angular/issues/29629

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 2015-11-29
      • 2015-05-22
      • 2018-12-26
      • 2012-04-07
      • 1970-01-01
      • 2014-01-22
      相关资源
      最近更新 更多