【发布时间】:2017-05-05 17:36:39
【问题描述】:
我创建了自定义 XHRBackend 类来全局捕获 401 错误。在 AuthService 中,我有 2 种使用 http 的方法 - login 和 refreshToken。所以我有这样的依赖链:Http -> customXHRBackend -> AuthService -> Http。我该如何解决这个问题?
export class CustomXHRBackend extends XHRBackend {
constructor(browserXHR: BrowserXhr,
baseResponseOptions: ResponseOptions,
xsrfStrategy: XSRFStrategy,
private router: Router,
private authService: AuthService) {
super(browserXHR, baseResponseOptions, xsrfStrategy);
}
createConnection(request: Request): XHRConnection {
let connection: XHRConnection = super.createConnection(request);
connection.response = connection.response
.catch(this.handleError.bind(this));
return connection;
}
handleError(error: Response | any) {
console.log('ERROR',error['status']);
if(error['status'] === 401) {
this.authService.logout();
this.router.navigate(['/']);
}
return Observable.throw(error);
}
}
AuthService.ts
@Injectable()
export class AuthService {
private loggedIn: boolean = false;
constructor(private http: Http) {
this.loggedIn = !!localStorage.getItem('authToken');
}
login(email: string, password: string): Observable<Response> {
let headers: Headers = new Headers();
headers.set('Content-Type', 'application/json');
return this.http.post('https://httpbin.org/post',
{
email: email,
password: password
},
{
headers: headers
})
.map((response) => {
let res = response.json();
// if (res['success']) {
if (res) {
localStorage.setItem('authToken', res['token']);
localStorage.setItem('refreshToken', res['refreshToken']);
console.log('logged');
this.loggedIn = true;
}
return response;
}
);
}
logout(): void {
localStorage.removeItem('authToken');
this.loggedIn = false;
console.log('Logged out');
}
isLogged(): boolean {
return this.loggedIn;
}
refreshToken(): Observable<Response> {
let headers: Headers = new Headers();
headers.set('token', localStorage.getItem('token'));
headers.set('refreshToken', localStorage.getItem('refreshToken'));
return this.http.get('https://httpbin.org/get', {
headers: headers
});
}
}
在 app.module.ts 中包含 CustomXHRBackend
{
provide: XHRBackend,
useFactory: (browserXHR: BrowserXhr,
baseResponseOptions: ResponseOptions,
xsrfStrategy: XSRFStrategy,
router: Router,
authService: AuthService) => {
return new CustomXHRBackend(browserXHR, baseResponseOptions, xsrfStrategy, router, authService);
},
deps: [BrowserXhr, ResponseOptions, XSRFStrategy, Router, AuthService]
}
【问题讨论】:
-
我看到了那个答案,但也许有比使用 setTimeout 更好的方法
-
我认为您不应该在您的
CustomXHRBackend中使用AuthService,因为XHRBackend的级别低于您的AuthService。这看起来像是一种反模式,即使只处理一次错误很方便,但如果有解决方案,它可能有点“hacky”。 -
那么第一条评论的答案呢? (或stackoverflow.com/questions/40860202/…)
标签: javascript http angular typescript dependency-injection