Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 为什么添加HTTP拦截器会导致CORS错误?_Angular_Cors_Interceptor - Fatal编程技术网

Angular 为什么添加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

我正在开发一个带有PHP REST Api的Angular 6应用程序。我的开发环境托管在本地主机上,因此首先我必须启用访问控制Allow Origin:*以绕过我遇到的任何CORS错误

最近,我一直在尝试使用拦截器实现JWT,以便将它们添加到我的HTTP请求中。当我启用了以下谷歌示例中的解释器后,我又开始出现CORS错误:

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);