扩展Angular2 Http提供程序和处理服务器

时间:2016-12-12 04:20:57

标签: angular angular2-services angular2-http

我按照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调用正在工作,但内置的调用不是自定义的)。不确定本地代码中究竟存在什么冲突。

2 个答案:

答案 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,否则会导致循环依赖性错误。