Angular 为什么添加HTTP拦截器会导致CORS错误?
我正在开发一个带有PHP REST Api的Angular 6应用程序。我的开发环境托管在本地主机上,因此首先我必须启用访问控制Allow Origin:*以绕过我遇到的任何CORS错误 最近,我一直在尝试使用拦截器实现JWT,以便将它们添加到我的HTTP请求中。当我启用了以下谷歌示例中的解释器后,我又开始出现CORS错误:Angular 为什么添加HTTP拦截器会导致CORS错误?,angular,cors,interceptor,Angular,Cors,Interceptor,我正在开发一个带有PHP REST Api的Angular 6应用程序。我的开发环境托管在本地主机上,因此首先我必须启用访问控制Allow Origin:*以绕过我遇到的任何CORS错误 最近,我一直在尝试使用拦截器实现JWT,以便将它们添加到我的HTTP请求中。当我启用了以下谷歌示例中的解释器后,我又开始出现CORS错误: blocked by CORS policy: Response to preflight request doesn't pass access control chec
blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header
我肯定这和我的拦截器有关,因为当我把它注释掉时,它又能工作了。下面是我想要使用的拦截器的代码:
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from
'@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/index';
import {AuthService} from './auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(public auth: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
req = req.clone({
setHeaders: {
'Content-Type' : 'application/json; charset=utf-8',
// 'Accept' : 'application/json',
'Authorization': `Bearer ${this.auth.getToken()}`
}
});
return next.handle(req);
}
}
下面是我用来发送HTTP请求的登录服务:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ServerResponse } from './server-response';
import {MessagesService} from './messages.service';
import {AuthService} from './auth.service';
@Injectable({
providedIn: 'root'
})
export class LoginService {
constructor(private http: HttpClient,
private ms: MessagesService,
private auth: AuthService) { }
login(formData) {
this.ms.clear();
console.log('JSON data', JSON.stringify((formData)));
console.log(this.auth.getToken());
return this.http.post('http://jpapp.com/api/login/login.php', JSON.stringify(formData))
.subscribe((rs: ServerResponse) => {
console.log('%cPost Success', 'color: green;');
console.log(rs);
}, (error) => ({status: -99, message: error}));
}
}
如果我删除了拦截器,Requet头如下所示(这就是我尝试将内容类型更改为纯文本的原因):
当我启用拦截器时,请求头如下所示:
Provisional headers are shown
Access-Control-Request-Headers: authorization,content-type
Access-Control-Request-Method: POST
Origin: http://localhost:4200
Referer: http://localhost:4200/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
我已经读到,我可能可以通过chrome扩展绕过这一点,但我想在安装扩展之前先知道我的代码中是否有什么内容
欢迎提供任何信息 更新
编辑:我应该提到,我发现将req.clone()设置为空白的原因是,预飞行只发生在复杂的而不是简单的cors请求上。在我的情况下,只要添加自定义标头,或者执行任何使其不再是简单请求的操作,默认情况下,它就会使用OPTIONS方法而不是POST方法发送飞行前请求。本文非常好地解释了cors和一个简单与复杂的请求:
飞行前响应错误与代码本身无关。问题在于我的IIS 10 web服务器的配置
在本文之后:我将所需的cors节点添加到我的web.config文件中,现在它可以正常工作了
我可以通过安装Allow控件Allow Origin:*Chrome扩展绕过飞行前请求CORS错误
只有当我保持默认URL匹配时,它似乎仍然有效。*://*/*/*
如果我将其更改为匹配我的URL,我会再次收到CORS错误,但这可能只是我的模式匹配问题。如果能解释一下它是如何工作的,那就太好了
我仍然在寻找一个原因,为什么通过拦截器传递授权会破坏服务器访问控制允许源:*因为我相信,一旦我实际部署此应用程序和api,我会再次遇到这个问题。将此扩展与默认配置一起使用也是一个PITA,因为它会破坏一堆站点。我在登录中获取令牌时遇到了同样的问题,我通过在拦截器请求中添加if-else解决了这个问题
const yourToken = this.auth.getToken();
if (yourToken) {
req = req.clone({
setHeaders: {
'Content-Type': 'application/json; charset=utf-8',
Accept: 'application/json',
Authorization: `Bearer ${yourToken}`
}
});
} else {
req = req.clone({
setHeaders: {
'Content-Type': 'application/json; charset=utf-8',
Accept: 'application/json'
}
});
}
return next.handle(req);
我通过检查请求中是否存在自定义头来解决这个问题。每当我向get请求添加头时,我都会注意到错误,并且在没有头的情况下可以正常工作。所以我做了这个
if(!(req.headers.get('No-auth'))| |((req.headers.get('No-auth')=='True')&&(req.headers.get('TokenRefresh')=='False'))在此处输入代码{返回下一个.handle(req.clone())}
如果请求中没有自定义头,则表示未提供头,这样做时,它只是克隆原始请求。如果只发送空对象,会怎么样
req=req.clone()
,您还收到CORS吗?如果我只发送一个空对象,我不会收到CORS错误
Provisional headers are shown
Accept: application/json, text/plain, */*
Content-Type: text/plain
Origin: http://localhost:4200
Referer: http://localhost:4200/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Provisional headers are shown
Access-Control-Request-Headers: authorization,content-type
Access-Control-Request-Method: POST
Origin: http://localhost:4200
Referer: http://localhost:4200/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
const yourToken = this.auth.getToken();
if (yourToken) {
req = req.clone({
setHeaders: {
'Content-Type': 'application/json; charset=utf-8',
Accept: 'application/json',
Authorization: `Bearer ${yourToken}`
}
});
} else {
req = req.clone({
setHeaders: {
'Content-Type': 'application/json; charset=utf-8',
Accept: 'application/json'
}
});
}
return next.handle(req);