我按照this文章扩展了Http提供程序并创建了自己的自定义Http提供程序。现在我试图捕获所有服务器异常,并根据状态代码需要采取适当的措施。
http.service.ts:
@Injectable()
export class HttpService extends Http {
constructor(backend: XHRBackend, options: RequestOptions) {
let token = localStorage.getItem('auth_token'); // your custom token getter function here
options.headers.set('Authorization', `Bearer ${token}`);
super(backend, options);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
let token = localStorage.getItem('auth_token');
if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
if (!options) {
// let's make option object
options = { headers: new Headers() };
}
options.headers.set('Authorization', `Bearer ${token}`);
} else {
// we have to add the token to the url object
url.headers.set('Authorization', `Bearer ${token}`);
}
return super.request(url, options).catch(this.catchAuthError(this));
}
private catchAuthError(self: HttpService) {
//I want to execute this function whenever there is any error from the server,
//but control is not coming here.
return (res: Response) => {
console.log("This is from the proxy http", res);
if (res.status === 401 || res.status === 403) {
// if not authenticated
console.log("Do something");
}
return Observable.throw(res);
};
}
}
Assets.service.ts:
import { HttpService } from './http.service';
@Injectable()
export class DataService {
constructor(private _http: HttpService) {
login(userName: string, password: string) {
const headers = new Headers();
headers.append("Authorization", 'Basic ' + btoa(userName + ":" + password));
headers.append("Content-Type", 'text/plain');
const requestUrl = this.loginResource + userName;
return this._http.get(requestUrl, { headers: headers })
.map((response: Response) => {
let res = response.json();
this.token = response.headers.get('token')
return res;
});
}
}
}
app.module.ts:
import { HttpService } from './services/http.service';
@NgModule({
imports: [BrowserModule, HttpModule, ...],
declarations: [...],
providers: [
{ provide: LocationStrategy, useClass: HashLocationStrategy },
{
provide: HttpService,
useFactory: (backend: XHRBackend, options: RequestOptions) => {
return new HttpService(backend, options);
},
deps: [XHRBackend, RequestOptions]
}
],
bootstrap: [AppComponent],
})
export class AppModule {
}
修改 我的自定义Http提供程序没有进行xhr调用,即使在扩展http之后也进行了操作,它仍在调用内置的http.request。
我创建了一个plnkr并且自定义Http调用正在那里工作,但不在我的本地代码中(xhr调用正在工作,但内置的调用不是自定义的)。不确定本地代码中究竟存在什么冲突。
答案 0 :(得分:0)
return super.request(url, options).catch(this.catchAuthError(this));
应该是
return super.request(url, options).catch(this.catchAuthError.bind(this));
或
return super.request(url, options).catch((err) => this.catchAuthError(err));
和
private catchAuthError (self: HttpService) {
应该是
private catchAuthError (err) {
答案 1 :(得分:0)
将您的扩展类提供为useClass
值:
{
provide : Http,
useClass:AppHTTPInterceptor,
deps: [XHRBackend, RequestOptions, AnyOtherService]
},
AnyOtherService
不应该依赖Http
,否则会导致循环依赖性错误。