簡體   English   中英

如何在Angular 4中的http狀態200響應的.map中引發可觀察到的錯誤

[英]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

經過大量的研究,我現在知道為什么我的代碼失敗了。 但是我仍然沒有解決辦法!

HttpInterceptorHttpInterceptor的方法..... 但是 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"}));
        }
}

找到我今天嘗試的示例代碼的屏幕截圖, 調用服務的組件代碼

瀏覽器console.log輸出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM