问题
I'm just discovering the new Angular 4.3.x HttpClient
Module, and I may very well be overlooking something simple.
I would like to know if it is possible to register a custom JSON Deserializer and still get the benefit of the typed HttpClient
get/post/put. It happens that for performance reason, my backend returns JSOG, which is an extension of JSON, instead of JSON
content.
Currently I make all my requests using a normal get(url, {responseType: 'text'})
, and then run the response through RxJs Map Operation to transform the Observable<string>
in the Observable that I want, returning JSOG.parse(responseString)
.
Did I miss a solution using an Interceptor of some kind? Thanks a lot for your advice.
回答1:
You can just implement an HttpInterceptor and intercept the response and mutate the body as you wish before it's return to the caller.
I'm doing something similar to intercept Microsoft ASP.NET format dates returned from my API and turning them into actual Date instances.
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpInterceptor, HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent } from '@angular/common/http';
@Injectable()
export class Interceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {
if (event instanceof HttpResponse) {
const resp: HttpResponse<any> = event;
// Mutate the body, replace ASP.NET Dates with actual local Date objects.
let body: {} = resp.body;
this.recurseBody(body);
}
});
}
private recurseBody(body: {}) {
if (!body) {
return;
}
for (let key in body) {
if (body.hasOwnProperty(key)) {
let element = body[key];
if (typeof element === 'object') {
this.recurseBody(element);
} else if (typeof element === 'string') {
// Check for a MS-format Date with optional TZ offset.
const matched = /\/Date\(([-]?\d{1,15})([\+-][01][0-3][0-5][0-9])?\)\//.exec(element);
if (matched) {
let tzOffsetMs = 0;
const tz = matched[2] || '';
if (tz) {
const hours = parseInt(tz.substr(0, tz.length - 2), 10);
const mins = parseInt(tz.substr(tz.length - 2, 2), 10);
const tzOffsetMins = mins + hours * 60;
tzOffsetMs = tzOffsetMins * 60 * 1000;
}
// Create a UTC Date object.
const date = new Date(+matched[1] + tzOffsetMs);
// Get the timezone offset for the local time (in minutes) and convert to ms.
const tzOffset = date.getTimezoneOffset() * 60 * 1000;
// Create a local date by using the offset
const localDate = new Date(date.getTime() + tzOffset);
console.log('convert ' + element + ' to ' + date + ' offset ' + date.getTimezoneOffset() + ' local = ' + localDate);
// Set the local date.
body[key] = localDate;
}
}
}
}
}
}
来源:https://stackoverflow.com/questions/46215105/angular-httpclient-custom-json-parser-jsog