HttpRequest和reportProgress没有工作或弄乱我的请求

时间:2018-04-16 14:53:56

标签: angular file-upload httprequest angular-httpclient

我正在使用Angular 5实现文件上传服务,我想向用户提供有关上传进度的一些反馈。我发现有几个页面建议使用Angulars reportProgress附带的HttpClient参数,但我无法使其正常工作。

我为所有的http请求使用了一个包装类,然后执行一些逻辑,最后所有请求都以调用的方法结束:

public request(request: HttpRequest<any>, options?: any): Observable<any> {
  return this.httpClient.request(request.method, request.url, {
    body: request.body,
    headers: request.headers,
    responseType: request.responseType,
    ...options
  });
}

然后我将上传(后)调用传递给它,{ reportProgress: true }options。这根本不起作用,请求没有改变。所以我怀疑,我实际上需要在HttpRequest构造函数中使用reportProgress - 参数来使其工作并相应地更改我的代码:

public request(request: HttpRequest<any>, options?: any): Observable<any> {
  return this.httpClient.request(
    new HttpRequest(request.method, request.url, request.body, {
      headers: request.headers,
      responseType: request.responseType,
      ...options
    })
  );
}

这会导致更奇怪的行为,现在无论我的选项是什么样的,我总是只收到{type: 0}作为请求的回复。

我在监督什么?我使用Angular 5.1.1,现在我真的有点困惑。

所以为了给出一个明确的例子,我现在收到这两个HttpRequests的相同响应:

{  
  "url":"http://127.0.0.1:8888/test",
  "body":{  
   "data":"testdata"
  },
  "reportProgress":false,
  "withCredentials":false,
  "responseType":"json",
  "method":"POST",
  "headers":{ some-headers ... }
}

和此请求:

{  
  "url":"http://127.0.0.1:8888/api/pages",
  "body":{  
    "pageUrl":"http://localhost:1234/"
  },
  "reportProgress":true,
  "withCredentials":false,
  "responseType":"json",
  "method":"POST",
  "headers":{ some-headers ... }
}

6 个答案:

答案 0 :(得分:5)

此方法可能会有所帮助

public progress: number = 0;
public message: string = "";

constructor(private http: HttpClient) {}

onSubmit() {
    // replace with your request data
    const formModel = this.userForm.value;
    let formData = new FormData();

    formData.append("upload", formModel.upload);

    const uploadReq = new HttpRequest('POST', 'api/Upload', formData, {
        reportProgress: true,
    });

    this.http.request(uploadReq).subscribe((event) => {
        if (event.type === HttpEventType.UploadProgress) {
            this.progress = Math.round(100 * event.loaded / event.total);
        }
        else if (event.type === HttpEventType.Response) {
            this.message = event.body.toString();
        }
    });
}

答案 1 :(得分:3)

我解决了这些问题。实际上,问题中描述的行为涉及两件事。

首先...... rtfm! https://angular.io/api/common/http/HttpClient

  

可以用两种方法之一调用此方法[HttpClient.request()]。可以将HttpRequest实例作为唯一参数直接传递,也可以将方法作为第一个参数传递,将字符串URL作为第二个参数传递,将选项哈希作为第三个传递。

     

如果直接传递HttpRequest对象,将返回原始HttpEvent流的Observable。

这解释了为什么我的两个请求(均以HttpRequest从现在开始传递{type: 0},无论reportProgress - 参数是true还是false

另一方面,仅接收SENT事件({type: 0})是后端本身的配置错误。

答案 2 :(得分:1)

return this.http.request('POST', api_enpoint , { body: body, headers: headers, reportProgress: true, withCredentials: true }).map(httpResponse => {
   console.log(httpResponse);
});

您需要以这种方式传递请求(而不是传递httpRequest对象)(HTTP和https都适用)

答案 3 :(得分:1)

连同{reportProgress:true}一起,您需要发送{observe: '事件'}

this.httpClient.post(environment.uploadDocument, file, { reportProgress: true, observe: 'events' })
.subcribe(data =>{
if (data['type'] === HttpEventType.UploadProgress) {
   console.log('loaded ', data['loaded'], '   total  -', data['total']);
   }
})

答案 4 :(得分:0)

阅读https://stackoverflow.com/a/54899930/1429439之后,我添加了 observe:'events'参数,并开始在订阅中接收HttpEvents。

答案 5 :(得分:0)

上传表单数据以及标题详细信息

此摘要将帮助ou上传表单数据,并且在订阅时您也可以实现进度条

uploadMyImage(formData: any) {
    const httpOptions = new HttpHeaders({
      'Content-Type': 'multipart/form-data', 'boundary': 'something'
      });
    return this.http.post('http://localhost:4000/api/upload', formData, { reportProgress: true, observe: 'events', headers: httpOptions });
  }