为啥我的 API 中没有启用 CORS?

Posted

技术标签:

【中文标题】为啥我的 API 中没有启用 CORS?【英文标题】:Why is CORS not being enabled in my API?为什么我的 API 中没有启用 CORS? 【发布时间】:2017-08-08 15:34:21 【问题描述】:

我有一个简单的 API (Web Api 2),我尝试在其中熟悉 Bearer 身份验证。

我可以确认令牌端点正在使用 Postman 和简单的 ajax 调用:

$.ajax(
    url: "http://localhost:51802/token",
    type: "POST",
    contentType: "application/x-www-form-urlencoded",
    data: 
          grant_type: "password",
          userName: "foo",
          password: "password123"
    
).done(function(data) 
    console.log(data);
).fail(function(err) 
    console.log(err);
);

客户端是一个相当简单的淘汰应用程序,它使用 npm http-server 运行,因此我需要在我的 API 上启用 CORS 来进行这些调用。但是,我尝试的所有方法似乎都没有任何效果(意味着不存在 CORS 标头):

//1
public static void Register(HttpConfiguration config)

     config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
     /*remaining out of the box configuration*/


//2
public void ConfigureAuth(IAppBuilder app)

    app.UseCors(CorsOptions.AllowAll);
    /*remaining out of the box configuration*/

在运行节点 http-server 的 Web 应用程序中使用与上述相同的 javascript 调用总是会导致 2 个错误:

    加载资源失败:服务器响应状态为 400 (Bad Request) ("error":"unsupported_grant_type") XMLHttpRequest 无法加载 http://localhost:51802/token。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://localhost:8080' 不允许访问。响应的 HTTP 状态代码为 400。

检查 Postman 中的标题,我找不到任何与 CORS 相关的条目:

Cache-Control →no-cache
Content-Length →641
Content-Type →application/json;charset=UTF-8
Date →Fri, 17 Mar 2017 06:58:54 GMT
Expires →-1
Pragma →no-cache
Server →Microsoft-IIS/10.0
Set-Cookie →.AspNet.Cookies=CiveOcfPNVqn_sVcJSQdi7VuqcleAd_Z9TD5Fff5m3lI3oZ3uVmThZHClXIAgwqByGoOlhfaCSHM8SwQ_GylajAnPdb0Ta6jmSl-M-CDnNYGdghibUWzSn_6-wgnNov_FGjkX8DSFoFvIYshFuppzbauS8MvUQkiDGVQg5pOvplaqcjD00SnsQMYssd5XQJGtb4NE35rOiF0Uk6hE45QxjAIUaq9LGVy; path=/; HttpOnly
X-Powered-By →ASP.NET
X-SourceFiles →=?UTF-8?B?QzpcUHJvamVrdGVcWWFpYlxZYWliLkFwaVxUb2tlbg==?=

我很确定我的 API 或客户端缺少一些非常基本的配置,但我不知道它是什么。

【问题讨论】:

【参考方案1】:

为了启用 CORS,我们需要为所有控制器设置来源、标题、方法。

我们可以通过以下两种方法之一来做到这一点。

1.向控制器添加属性

 `[EnableCors(origins: "*", headers: "*", methods: "*")]
    public class MyController : ApiController
    `

2。在我们的 Web.config 文件中进行配置

`<system.webServer>
     <httpProtocol>
       <customHeaders>
         <add name="Access-Control-Allow-Origin" value="*" />
         <add name="Access-Control-Allow-Headers" value="Content-Type" />
         <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />
       </customHeaders>
     </httpProtocol>
 </system.webServer>`

【讨论】:

从我的问题中可以看出,我已经安装了该软件包,我尝试全局启用 CORS,而不是基于每个控制器或每个操作 为了启用 CORS,我们需要为所有控制器设置来源、标头、方法,我们可以通过属性或 web 配置方法来做到这一点,更新的答案可能会有所帮助。【参考方案2】:

问题确实是“客户”。

正确的设置是使用app.UseCors(CorsOptions.AllowAll);

在此之后,我确定 http-server (http-server -c-1) 没有缓存任何文件,并从 Google Chrome 中删除了所有临时存储的文件。 如果没有这个,就会提供旧的 javascript 代码,这是导致这些错误消息的原因之一。

现在我可以使用问题中的代码进行身份验证,然后访问受保护的资源:

$.ajax(
     url: "http://localhost:51802/api/values",
     type: "GET",
     crossDomain: true,
     headers: 
        Authorization: "Bearer U90P0Lh-Q8ZeMyZXDzLSQPCfJVIXlmj94GHjLUY0M_B_Zfm-jojao7lUjZvcz_pLerS5BKwMrQk29eZI618mUZyhZ3gm0bjAy3WCZ4dYS1pv4vTaR8re6i8uriwsmtkm3FMwMxWOIPR0thLyYsjFQ7XM8s7K3pkUiIuEixFT8mG8wMnHe1FD1EoJxhadT7gbmYhm-MRO2cNuf2K8gx4EOyjwM2bsgdhtARA3oSDq5SezFRxLzDtZ32PfSpG61v9jOqIiJ0pWdtgeDSY2W7EusVzyDu0V7MB8kAc4uqNyjlCZFDiEn-mLvJkcqXpRf..."
     
).done(function(data) 
    console.log(data);
).fail(function(err) 
    console.log(err);
);

【讨论】:

以上是关于为啥我的 API 中没有启用 CORS?的主要内容,如果未能解决你的问题,请参考以下文章

Cors 中启用的所有标头,WebConfig 和 WebApiConfig 之间没有冲突,为啥我的 WebApi 返回 405 错误?

为啥即使未启用 CORS,HTTP 请求也会在 Action 中处理? [复制]

在 Web Api Core 1.1 中启用 Cors

如何在我的 Django REST api 上调试启用 CORS

在 Azure 上为 .NET Web Api 启用 CORS

在 wordpress api 中启用 CORS