那裏似乎不幸的是不要被一個齊磊傳遞給所內的角度HttpClient的使用JSON.parse方法的一種方式。下面是他們叫其中JSON.parse源代碼: https://github.com/angular/angular/blob/20e1cc049fa632e88dfeb00476455a41b7f42338/packages/common/http/src/xhr.ts#L189
角如果響應類型設置爲「JSON」(你可以看到這個上線183)將只解析響應。如果您未指定響應類型,則Angular默認爲「json」(https://github.com/angular/angular/blob/20e1cc049fa632e88dfeb00476455a41b7f42338/packages/common/http/src/request.ts#L112)。
所以你可以使用「text」的響應類型並自己解析json。或者你可能只是懶惰和序列化,然後反序列化響應(JSON.parse(JSON.stringify(res.body), reviver)
)。
不必修改每一個電話,你可以創建類似下面的攔截器:
JSON-interceptor.ts
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/map';
// https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts#L18
const XSSI_PREFIX = /^\)\]\}',?\n/;
/**
* Provide custom json parsing capabilities for api requests.
* @export
* @class JsonInterceptor
*/
@Injectable()
export class JsonInterceptor implements HttpInterceptor {
/**
* Custom http request interceptor
* @public
* @param {HttpRequest<any>} req
* @param {HttpHandler} next
* @returns {Observable<HttpEvent<any>>}
* @memberof JsonInterceptor
*/
public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.responseType !== 'json') {
return next.handle(req);
}
// convert to responseType of text to skip angular parsing
req = req.clone({
responseType: 'text'
});
return next.handle(req).map(event => {
// Pass through everything except for the final response.
if (!(event instanceof HttpResponse)) {
return event;
}
return this.processJsonResponse(event);
});
}
/**
* Parse the json body using custom revivers.
* @private
* @param {HttpResponse<string>} res
* @returns{HttpResponse<any>}
* @memberof JsonInterceptor
*/
private processJsonResponse(res: HttpResponse<string>): HttpResponse<any> {
let body = res.body;
if (typeof body === 'string') {
const originalBody = body;
body = body.replace(XSSI_PREFIX, '');
try {
body = body !== '' ? JSON.parse(body, (key: any, value: any) => this.reviveUtcDate(key, value)) : null;
} catch (error) {
// match https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts#L221
throw new HttpErrorResponse({
error: { error, text: originalBody },
headers: res.headers,
status: res.status,
statusText: res.statusText,
url: res.url || undefined,
});
}
}
return res.clone({ body });
}
/**
* Detect a date string and convert it to a date object.
* @private
* @param {*} key json property key.
* @param {*} value json property value.
* @returns {*} original value or the parsed date.
* @memberof JsonInterceptor
*/
private reviveUtcDate(key: any, value: any): any {
if (typeof value !== 'string') {
return value;
}
if (value === '0001-01-01T00:00:00') {
return null;
}
const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (!match) {
return value;
}
return new Date(value);
}
}
然後,你必須向它提供的模塊:
* .module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { JsonInterceptor } from '...';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: JsonInterceptor,
multi: true
}
]
})
...
在這個例子中,我試圖模仿角度如何儘可能地進行解析。它們似乎不會導出HttpJsonParseError,因此我無法將錯誤轉換爲該類型。這可能不是完美的,但我希望它能得到這個想法。
這裏是一個正在運行的例子(看在控制檯中看到的日期解析到):https://stackblitz.com/edit/angular-qqbmcx
我創建了一個功能要求在這裏: https://github.com/angular/angular/issues/21079
難道不可能將這個reviver函數重定位到您期望的對象,即Person? – Laurens
人最有可能是一個接口,所以它沒有方法 –