繁体   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