[英]Handling a multipart Response body in Angular
我在Angular中收到一個包含多個部分的響應正文,但應用程序未正確處理響應。 事實證明,Angular中的HttpClient無法正確解析多部分響應主體(請參閱GitHub上的此問題 )。
HttpClient
只是在HttpResponse
對象的主體內返回原始的multipart響應,而我希望在我的HttpResponse
對象內可以訪問來自multipart響應的application/json
塊。
如何正確處理Angular中的多部分響應?
我從stackoverflow上的另一篇文章中獲得了極大的啟發,提出了一個快速而骯臟的解決方案,並創建了一個HTTP攔截器類,該類顯示了如何解析多部分響應。 攔截器從多部分響應( multipart/mixed
, multipart/form-data
或multipart/related
)返回第一個“ application / json”部分作為響應主體。 通過映射,可以輕松地將其他內容類型的其他解析器添加到類中。
我將在此處分享此代碼,這可能會給其他人帶來啟發:
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class MultipartInterceptService implements HttpInterceptor {
private parserMap = {
'application/json': JSON.parse,
};
private parseMultipart(multipart: string, boundary: string): any {
const dataArray: string[] = multipart.split(`--${boundary}`);
dataArray.shift();
dataArray.forEach((dataBlock) => {
const rows = dataBlock.split(/\r?\n/).splice(1, 4);
if (rows.length < 1) {
return;
}
const headers = rows.splice(0, 2);
const body = rows.join('');
if (headers.length > 1) {
const pattern = /Content-Type: ([a-z\/+]+)/g;
const match = pattern.exec(headers[0]);
if (match === null) {
throw Error('Unable to find Content-Type header value');
}
const contentType = match[1];
if (this.parserMap.hasOwnProperty(contentType) === true) {
return this.parserMap[contentType](body);
}
}
});
return false;
}
private parseResponse(response: HttpResponse<any>): HttpResponse<any> {
const contentTypeHeaderValue = response.headers.get('Content-Type');
const body = response.body;
const contentTypeArray = contentTypeHeaderValue.split(';');
const contentType = contentTypeArray[0];
switch (contentType) {
case 'multipart/related':
case 'multipart/mixed':
case 'multipart/form-data':
const boundary = contentTypeArray[1].split('boundary=')[1];
const parsed = this.parseMultipart(body, boundary);
if (parsed === false) {
throw Error('Unable to parse multipart response');
}
return response.clone({ body: parsed });
default:
return response;
}
}
// intercept request and add parse custom response
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
map((response: HttpResponse<any>) => {
if (response instanceof HttpResponse) {
return this.parseResponse(response);
}
}),
);
}
}
該代碼從Content-Type
響應標頭讀取邊界,並使用該邊界將響應主體拆分為多個塊。 然后,它嘗試解析每個部分,並從響應中返回第一個成功解析的application/json
塊。
如果您有興趣返回另一個代碼塊,或者想要在最終響應中組合多個代碼塊,則需要使用自己的解析器或更改邏輯。 這將需要對代碼進行一些自定義。
注意:此代碼是實驗性的,經過嚴格測試,尚未投入生產,請謹慎使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.