Angular 带拦截器的 HTTPRequest 管道
Angular HTTPRequest pipe w/ interceptor
我目前正在尝试跟踪 angular 组件中的上传进度。该组件接受一个文件并调用一个服务,该服务将文件上传到服务器。
我们目前使用拦截器注入 header 和 auth-token。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (localStorage.getItem('token') != null) {
request = request.clone({
setHeaders: {
'X-Auth-Token': localStorage.getItem('token')
}
});
}
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
return event;
}),
catchError((error: any) => {
if (error.status === 401) {
localStorage.removeItem('token');
this.router.navigate(['/public/login']);
return of(error);
}
return throwError(error);
})
);
如果我在这里的 map() 之后放置一个 tap(),我可以接收点击注释并将它们记录到控制台。
我调用该服务并尝试使用 pipe/tap 在我的组件中获取上传进度
this.assetService.upload(formData).pipe(
map(data => console.log(data)),
tap(message => console.log(message))
).subscribe(data => { console.log(data); });
这里的pipe()/map()/tap()永远不会命中
理想情况下,我想使用组件中的 tap() 来计算上传的百分比,然后用它来更新进度条。
您可以使用此方法或方式使用 RxJs 的 tap/map/pipe
。
postImportExportFile(fileToUpload: File): Observable<MyObject> {
this.formData = new FormData();
this.formData.append('file', fileToUpload, fileToUpload.name);
const url = 'http://loclahost:4200/myPost/url/to/be/hit';
return this.http.post(url, this.formData, {
headers: new HttpHeaders({ 'upload': 'true' }), // I used this for change the interceptors accepts and content-type
reportProgress: true,
observe: 'events',
}).pipe(
retry(3),
map((event: HttpEvent<any>) => this.getEventMessage(event, fileToUpload)),
tap((t: MyObject) => {
return console.log(`post import export file for );
}),
catchError(this.handleError<MyObject>(url))
);
}
方法:
getEventMessage(event: HttpEvent<any>, file: File): MyObject{
const myObject= new MyObject();
switch (event.type) {
case HttpEventType.Sent:
myObject.eventType = UploadEventType.SENT; // This is an enum that help me to add a event type to my object
myObject.message = `Uploading file "${file.name}" of size ${file.size}.`;
break;
case HttpEventType.UploadProgress:
myObject.eventType = UploadEventType.PROGRESS;
const percentDone = Math.round(100 * event.loaded / event.total);
myObject.message = `File "${file.name}" is ${percentDone}% uploaded.`;
break;
case HttpEventType.Response:
console.log(`File "${file.name}" was completely uploaded!`);
myObject.eventType = UploadEventType.COMPLETED;
myObject.message = event;
break;
default:
myObject.eventType = UploadEventType.ERROR;
myObject.message = `File "${file.name}" surprising upload event: ${event.type}.`;
}
return myObject;
}
收到 object 后,您可以使用 if else case 检查事件是什么,然后根据需要进行工作。
在第一部分中,我使用了方法 postImportExportFile
,它是 post 方法调用并发送一个 header 用于更改拦截器值,例如 headerSettings['Content-Type'] = 'multipart/form-data';
,然后使用 observe输入:如 events
。
这有助于我们获取 HttpEvent
s,然后我们更改消息在我们这边进行检查和使用。第二种方法你可以直接使用,但我打破了它们并用作我自己的 object。
希望对您有所帮助,如果您需要进一步说明代码,请告诉我。
我目前正在尝试跟踪 angular 组件中的上传进度。该组件接受一个文件并调用一个服务,该服务将文件上传到服务器。
我们目前使用拦截器注入 header 和 auth-token。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (localStorage.getItem('token') != null) {
request = request.clone({
setHeaders: {
'X-Auth-Token': localStorage.getItem('token')
}
});
}
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
return event;
}),
catchError((error: any) => {
if (error.status === 401) {
localStorage.removeItem('token');
this.router.navigate(['/public/login']);
return of(error);
}
return throwError(error);
})
);
如果我在这里的 map() 之后放置一个 tap(),我可以接收点击注释并将它们记录到控制台。
我调用该服务并尝试使用 pipe/tap 在我的组件中获取上传进度
this.assetService.upload(formData).pipe(
map(data => console.log(data)),
tap(message => console.log(message))
).subscribe(data => { console.log(data); });
这里的pipe()/map()/tap()永远不会命中
理想情况下,我想使用组件中的 tap() 来计算上传的百分比,然后用它来更新进度条。
您可以使用此方法或方式使用 RxJs 的 tap/map/pipe
。
postImportExportFile(fileToUpload: File): Observable<MyObject> {
this.formData = new FormData();
this.formData.append('file', fileToUpload, fileToUpload.name);
const url = 'http://loclahost:4200/myPost/url/to/be/hit';
return this.http.post(url, this.formData, {
headers: new HttpHeaders({ 'upload': 'true' }), // I used this for change the interceptors accepts and content-type
reportProgress: true,
observe: 'events',
}).pipe(
retry(3),
map((event: HttpEvent<any>) => this.getEventMessage(event, fileToUpload)),
tap((t: MyObject) => {
return console.log(`post import export file for );
}),
catchError(this.handleError<MyObject>(url))
);
}
方法:
getEventMessage(event: HttpEvent<any>, file: File): MyObject{
const myObject= new MyObject();
switch (event.type) {
case HttpEventType.Sent:
myObject.eventType = UploadEventType.SENT; // This is an enum that help me to add a event type to my object
myObject.message = `Uploading file "${file.name}" of size ${file.size}.`;
break;
case HttpEventType.UploadProgress:
myObject.eventType = UploadEventType.PROGRESS;
const percentDone = Math.round(100 * event.loaded / event.total);
myObject.message = `File "${file.name}" is ${percentDone}% uploaded.`;
break;
case HttpEventType.Response:
console.log(`File "${file.name}" was completely uploaded!`);
myObject.eventType = UploadEventType.COMPLETED;
myObject.message = event;
break;
default:
myObject.eventType = UploadEventType.ERROR;
myObject.message = `File "${file.name}" surprising upload event: ${event.type}.`;
}
return myObject;
}
收到 object 后,您可以使用 if else case 检查事件是什么,然后根据需要进行工作。
在第一部分中,我使用了方法 postImportExportFile
,它是 post 方法调用并发送一个 header 用于更改拦截器值,例如 headerSettings['Content-Type'] = 'multipart/form-data';
,然后使用 observe输入:如 events
。
这有助于我们获取 HttpEvent
s,然后我们更改消息在我们这边进行检查和使用。第二种方法你可以直接使用,但我打破了它们并用作我自己的 object。
希望对您有所帮助,如果您需要进一步说明代码,请告诉我。