某个请求校验未登录返回302重定向跳转时报跨域错误。
请求头中有'X-Requested-With': 'XMLHttpRequest',xhr不允许跨域
解决办法:
后端和前端配合,返回响应的状态码和location属性,由前端替换url方式重新跳转location
注:不能返回302来重定向,因为浏览器自动执行302跳转其他页面,先监听到跨域报错后,再进到http的catchError,这时返回的xhr返回的status为0,无法进行正确逻辑判断
响应的http-intercept 拦截器代码:
intercept(httpRequest: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let httpRequestUpdated = httpRequest.clone({ withCredentials: true });
if (environment.production) {
httpRequestUpdated = httpRequest.clone({ setHeaders: { 'X-Requested-With': 'XMLHttpRequest' } });
}
return next.handle(httpRequestUpdated).pipe(
map(event => {
if (event instanceof HttpResponse) {
return event.clone({ body: event.body.body });
} else {
return event;
}
}),
catchError(event => {
console.log('intercept', event);
const redirect = event.headers.get('Location');
// location.href = `${window.location.origin}/api/login`;
if (event.status === 401 && !isNil(redirect)) {
// Handle page redirect
window.location.href = redirect;
} else if (event.status === 405 && !event.url.contains('logout')) {
this.ticketService.logout().subscribe();
}
return throwError(event);
})
);
}
xhr的status值为0的原因
The status attribute must return the result of running these steps:
1. If the state is UNSENT or OPENED, return 0.
2. If the error flag is set, return 0.
3. Return the HTTP status code.