[英]How to throw observable error in .map for a http status 200 response in Angular 4
在我的Angular 4應用中,我使用http post調用服務器的登錄api。 服務器始終以stauts 200響應,無論登錄是否成功。 我想根據服務器響應數據拋出錯誤。
export class AuthenticationService {
...
login(username: string, password: string): Observable<any> {
let body = `method=login&username=${username}&password=${password}`;
return this.http.post('http://localhost/rest.php', body)
.map((response: Response) => {
let responsedata = response.json();
if (responsedata && responsedata.success == 1) {
localStorage.setItem('loggedin',1);
} else {
// Not logged in successfully
Observable.throw(new Error('Not logged in'));
}
});
}
和我的代碼調用login()
trytologin() {
this.loading = true;
this.authenticationService.login(this.model.username, this.model.password)
.subscribe(
data => {
// Always returns here regarless of result of login
this.router.navigate([this.returnUrl]);
},
error => {
// ONLY returns here on a NON-server 200 status
this.alertService.error(error);
this.loading = false;
});
}
我想我可以使用HttpInterceptor
截取響應並更改標頭,但這似乎HttpInterceptor
過頭了。 還有另一種方法可以使subscribe
錯誤從200狀態響應中觸發嗎?
編輯
我嘗試實現HttpInterceptor
失敗。
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse,HttpHeaderResponse, HttpErrorResponse} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
@Injectable()
export class LoginInterceptor implements HttpInterceptor {
constructor() {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Need to .map so we can go through each event looking for the HttpResponse
// Can't use .do() as it doesn't update per the docs
return next.handle(req).map(event => {
if (event instanceof HttpResponse) {
let e2 = new HttpErrorResponse({status: 405, statusText: 'Auth error'});
// return Observable(e2); // Cannot return as HttpErrorResponse is NOT part of HttpEvent<any>
Observable.throw(e2); // <-- Still triggers the success in .subscribe(). Does NOT trigger the .subscribe() error
event = event.clone({status: 405, statusText: 'Auth error'}); // <-- change the event status. Can't return HttpErrorResponse as
}
return event;
});
}
}
總是調用.subscribe()
成功。
我錯了 :-/
編輯#2
經過大量的研究,我現在知道為什么我的代碼失敗了。
但是我仍然沒有解決辦法!
HttpInterceptor
是
HttpInterceptor
的方法.....
但是 Observer.throw()
僅在HttpClient.post()
在同一域中才有效!
如果將post()發布到本地主機,則會調用subscribe()錯誤。
如果我將post()調用到另一個域,它將無法調用subscribe()錯誤。
我在
Observer.throw()
之后緊接着放置了
console.log()
Observer.throw()
。
如果我有其他域,則有日志輸出。
如果域相同,則
沒有日志輸出。
我不知道這是否是CORS問題,因為我可以控制服務器輸出,並且包含
Access-Control-Allow-Origin: *
標頭項。
這可能是
HttpClient
和/或
HttpInterceptor
的錯誤
HttpInterceptor
?
還是rxjs有問題?
編輯#3
如果我只是在intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
返回Observable.throw()
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
塊, intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
觸發我的錯誤代碼。 但是,這只會在http請求上觸發。 我需要處理並在http響應上引發錯誤。 為此,我需要使用return next.handle(req).map()
查找每個HttpResponse
事件。
如果我嘗試在map()
執行Observer.throw()
,則它不會觸發我的錯誤代碼,並且不會在任何地方被捕獲。 Observer.throw()
之后的行被執行。
我無法從map()
return Observer.throw()
,因為它是錯誤的返回類型。
但是,在map()
調用普通的JavaScript throw()
map()
會觸發我的錯誤代碼。
我不確定是否最好使用throw()
還是應該做其他事情。
您將必須導入適當的Observable庫和方法,以使此代碼像
import { HttpInterceptor, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/Observable/of';
您可以截取響應,然后從該響應中做出決定,
export class YourInterceptor implements HttpInterceptor{
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>{
//check your conditions if fall true send this response as given //below
return Observable.throw(new HttpErrorResponse({status:401, statusText:"Error of auth"}));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.