我喜欢覆盖默认选项的想法,这似乎是一个不错的解决方案。
但是,如果您打算扩展 Http 类。请务必通读!
这里的一些答案实际上显示了 request() 方法的错误重载,这可能导致难以捕捉的错误和奇怪的行为。这是我自己偶然发现的。
此解决方案基于 Angular 4.2.x 中的 request() 方法实现,但应该与未来兼容:
import {Observable} from 'rxjs/Observable';
import {Injectable} from '@angular/core';
import {
ConnectionBackend, Headers,
Http as NgHttp,
Request,
RequestOptions,
RequestOptionsArgs,
Response,
XHRBackend
} from '@angular/http';
import {AuthenticationStateService} from '../authentication/authentication-state.service';
@Injectable()
export class Http extends NgHttp {
constructor (
backend: ConnectionBackend,
defaultOptions: RequestOptions,
private authenticationStateService: AuthenticationStateService
) {
super(backend, defaultOptions);
}
request (url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
if ('string' === typeof url) {
url = this.rewriteUrl(url);
options = (options || new RequestOptions());
options.headers = this.updateHeaders(options.headers);
return super.request(url, options);
} else if (url instanceof Request) {
const request = url;
request.url = this.rewriteUrl(request.url);
request.headers = this.updateHeaders(request.headers);
return super.request(request);
} else {
throw new Error('First argument must be a url string or Request instance');
}
}
private rewriteUrl (url: string) {
return environment.backendBaseUrl + url;
}
private updateHeaders (headers?: Headers) {
headers = headers || new Headers();
// Authenticating the request.
if (this.authenticationStateService.isAuthenticated() && !headers.has('Authorization')) {
headers.append('Authorization', 'Bearer ' + this.authenticationStateService.getToken());
}
return headers;
}
}
请注意,我以这种方式导入原始类 import { Http as NgHttp } from '@angular/http'; 以防止名称冲突。
这里解决的问题是request() 方法有两个不同的调用签名。当传递Request 对象而不是URL string 时,Angular 会忽略options 参数。所以这两种情况都必须妥善处理。
下面是如何将这个被覆盖的类注册到 DI 容器的示例:
export const httpProvider = {
provide: NgHttp,
useFactory: httpFactory,
deps: [XHRBackend, RequestOptions, AuthenticationStateService]
};
export function httpFactory (
xhrBackend: XHRBackend,
requestOptions: RequestOptions,
authenticationStateService: AuthenticationStateService
): Http {
return new Http(
xhrBackend,
requestOptions,
authenticationStateService
);
}
通过这种方法,您可以正常注入Http 类,但您的覆盖类将被神奇地注入。这使您可以轻松集成您的解决方案,而无需更改应用程序的其他部分(多态性在起作用)。
只需将httpProvider 添加到模块元数据的providers 属性即可。