【问题标题】:Missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel来自 CORS 预检通道的 CORS 标头“Access-Control-Allow-Headers”中缺少令牌“access-control-allow-headers”
【发布时间】:2015-11-26 18:21:46
【问题描述】:

我有两个 VS 项目:一个公开 MVC5 控制器,另一个是 Angular 客户端。我希望角度客户端能够查询控制器。 我阅读了许多线程并尝试了以下内容:

  • 我在服务器的网络配置中添加了这个:

    <system.webServer>
        <httpProtocol>
           <customHeaders>
                <clear />
                <add name="Access-Control-Allow-Origin" value="*" />
            </customHeaders>
        </httpProtocol>
    <system.webServer>
    
  • 我在控制器的操作上创建并使用了以下过滤器:

    public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            base.OnActionExecuting(filterContext);
        }
    }
    
  • 在 Angular 客户端中,我创建了以下拦截器:

    app.factory("CORSInterceptor", [
        function()
        {
            return {
                request: function(config)
                {
                     config.headers["Access-Control-Allow-Origin"] = "*";
                     config.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
                     config.headers["Access-Control-Allow-Headers"] = "Content-Type";
                     config.headers["Access-Control-Request-Headers"] = "X-Requested-With, accept, content-type";
                     return config;
                }
         };
    }
    ]);
    
    app.config(["$httpProvider", function ($httpProvider) {
        $httpProvider.interceptors.push("CORSInterceptor");
    }]);
    

根据 Firebug,这会导致以下请求:

OPTIONS //Login/Connect HTTP/1.1
Host: localhost:49815
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:50739
Access-Control-Request-Method: POST
Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-origin,content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

还有以下回复:

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/10.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-SourceFiles: =?UTF-8?B?RDpcVEZTXElVV2ViXEdhcE5ldFNlcnZlclxBU1BTZXJ2aWNlc1xMb2dpblxDb25uZWN0?=
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Request-Headers: X-Requested-With, accept, content-type
Date: Tue, 01 Sep 2015 13:05:23 GMT
Content-Length: 0

而且,Firefox 仍然使用以下消息阻止请求:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49815//Login/Connect. (Reason: missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).

【问题讨论】:

标签: angularjs asp.net-mvc cors preflight


【解决方案1】:

问题是,一些浏览器还不允许* 通配符用于Access-Control-Allow-Headers。具体来说,Firefox 69 及更早版本没有。见https://bugzilla.mozilla.org/show_bug.cgi?id=1309358

因此,为了确保您在所有浏览器中获得正确的行为,您发回的 Access-Control-Allow-Headers 值应明确列出您实际需要从前端代码访问的所有标头名称;例如,在问题的情况下:Access-Control-Allow-Headers: Content-Type

无需对所有标头名称进行硬编码即可实现此目的的一种方法是:让您的服务器端代码获取浏览器发送的 Access-Control-Request-Headers 请求标头的值,然后将其回显到 @ 的值中987654327@ 服务器发回的响应标头。

或者使用一些现有的库来为你的服务器启用 CORS。将 Access-Control-Request-Headers request-header 值回显到 Access-Control-Allow-Headers response-header 值是大多数 CORS 库通常会为您做的事情。

【讨论】:

  • 这个答案来自 2015 年,“Firefox 69 及更早版本不允许* 通配符”的论点仍然相关......因为 Firefox 68 是 2019 年的最新稳定版本:-(
【解决方案2】:

我在我的 .net c# mvc 应用程序和 Angular 8 客户端应用程序中进行了尝试,但它不起作用。在 web.config 中,我添加了

<httpProtocol>
  <customHeaders>
    <clear />
    <add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
    <add name="Access-Control-Allow-Headers" value="Content-Type"/>
  </customHeaders>
</httpProtocol>

在 global.axax.cs 文件中,我也添加了

    void MvcApplication_AuthenticateRequest(object sender, EventArgs e)
    {
        Context.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
    }

但它不起作用。在响应标头中的 chrome 中,它确实显示为:

访问控制允许标题:内容类型 访问控制允许来源:http://localhost:4200 访问控制允许来源:http://localhost:4200

但在请求标头中显示为

Access-Control-Request-Headers: access-control-allow-origin,content-type,x-iphoneclientid

而它需要有喜欢

x-iphoneclientid : 8E72FF50-548B

因为 x-iphoneclientid 是我在过滤器类中验证的令牌

    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {

        if (request == null || request.RequestUri == null)
        {
            return null;
        }
        // Write your Authentication code here
        IEnumerable<string> monsterApiKeyHeaderValues = null;

        // Checking the Header values
        if (request.Headers.TryGetValues("x-iphoneclientid", out monsterApiKeyHeaderValues))

上面的条件没有找到所以它拒绝它并且它没有到达控制器。

我什至在我的控制器中加入了跟随

[EnableCors("", "", "*")]

请指导一下

谢谢

【讨论】:

    【解决方案3】:

    通常,我阅读的线程会建议几个不必要的配置步骤,这会造成混乱。其实很简单……

    出于将跨站请求从 Angular 客户端发送到 ASP 控制器的简单目的:

    • 不需要角度拦截器。
    • 服务器端不需要自定义过滤器。
    • 唯一的强制修改是在服务器的 web.config 中添加它

      <system.webServer>
            <httpProtocol>
                <customHeaders>
                    <clear />
                    <add name="Access-Control-Allow-Origin" value="*" />
                    <add name="Access-Control-Allow-Headers" value="Content-Type"/>
                </customHeaders>
           </httpProtocol>
      </system.webServer>
      

    【讨论】:

    • 对于sailsjs,请参阅https://0.12.sailsjs.com/documentation/reference/configuration/sails-config-cors
    • 这在 Firefox 中不起作用,也不是最佳实践。您应该显式设置(在服务器上)Access-Control-Allow-Origin 的值以匹配 expected 来源。如果您需要在本地机器上进行测试并遇到 localhost 问题,只需在主机文件中添加以下行:127.0.0.1 yourwebsite.local。完成此步骤后,将服务器配置为使用Access-Control-Allow-Origin: yourwebsite.local 应答。如果您无权访问后端,请参阅此线程:stackoverflow.com/questions/3076414/…
    猜你喜欢
    • 2020-02-26
    • 2019-07-07
    • 2019-07-06
    • 2016-09-30
    • 2019-12-10
    • 2018-03-28
    • 2019-02-07
    • 2016-05-15
    相关资源
    最近更新 更多