我正在使用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 ... }
}
这种方法可能有帮助
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();
}
});
}
我解决了这些问题。实际上,问题中描述的行为涉及两件事。
首先...... rtfm! https://angular.io/api/common/http/HttpClient
可以用两种方法之一调用此方法[HttpClient.request()]。可以将HttpRequest实例作为唯一参数直接传递,也可以将方法作为第一个参数传递,将字符串URL作为第二个参数传递,将选项哈希作为第三个参数传递。
如果直接传递HttpRequest对象,将返回原始HttpEvent流的Observable。
这解释了为什么我的两个请求(两个都通过HttpRequest
从现在开始返回{type: 0}
,无论reportProgress
-paramter是true
还是false
。
另一方面,仅接收SENT事件(qazxsw poi)是后端本身的错误配置。
以及{reportProgress:true}你需要发送{observe:'events'}
{type: 0}
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']);
}
})
您需要以这种方式传递请求,而不是传递httpRequest对象(既适用于http也适用于https)
在阅读return this.http.request('POST', api_enpoint , { body: body, headers: headers, reportProgress: true, withCredentials: true }).map(httpResponse => {
console.log(httpResponse);
});
之后,我添加了observe:'events'参数并开始在我的订阅中接收HttpEvents。