Đáng tiếc là có vẻ không phải là một cách để vượt qua một người bình phục với phương pháp JSON.parse được sử dụng trong phạm vi góc HttpClient. Đây là mã nguồn cho nơi họ gọi JSON.parse: https://github.com/angular/angular/blob/20e1cc049fa632e88dfeb00476455a41b7f42338/packages/common/http/src/xhr.ts#L189
Góc sẽ chỉ phân tích phản hồi nếu kiểu phản hồi được đặt thành "json" (bạn có thể thấy điều này trên dòng 183). Nếu bạn không chỉ định kiểu phản hồi thì Angular sẽ mặc định là "json" (https://github.com/angular/angular/blob/20e1cc049fa632e88dfeb00476455a41b7f42338/packages/common/http/src/request.ts#L112).
Vì vậy, bạn có thể sử dụng loại phản hồi "văn bản" và phân tích cú pháp chính con cháu. Hoặc bạn chỉ có thể lười biếng và tuần tự hóa và sau đó deserialize phản ứng (JSON.parse(JSON.stringify(res.body), reviver)
).
Thay vì thay đổi mỗi cuộc gọi bạn có thể tạo ra một đánh chặn như sau:
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);
}
}
Sau đó, bạn phải cung cấp cho nó trong module của bạn:
* .module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { JsonInterceptor } from '...';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: JsonInterceptor,
multi: true
}
]
})
...
Trong ví dụ này, tôi đã cố gắng bắt chước cách góc độ phân tích cú pháp càng nhiều càng tốt. Họ dường như không xuất khẩu HttpJsonParseError vì vậy tôi không thể bỏ lỗi cho loại đó. Nó có lẽ không phải là hoàn hảo nhưng tôi hy vọng nó được ý tưởng trên.
Dưới đây là một ví dụ chạy (nhìn vào giao diện điều khiển để xem ngày phân tích cú pháp): https://stackblitz.com/edit/angular-qqbmcx
Tôi tạo ra một yêu cầu tính năng ở đây: https://github.com/angular/angular/issues/21079
Sẽ không thể di chuyển chức năng này cho đối tượng bạn đang mong đợi, tức là Người? – Laurens
Người có nhiều khả năng là một giao diện, vì vậy nó không có methos –