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