CORS POST 请求不起作用 - 选项(错误请求) - 不允许来源
Posted
技术标签:
【中文标题】CORS POST 请求不起作用 - 选项(错误请求) - 不允许来源【英文标题】:CORS POST Requests not working - OPTIONS (Bad Request) - The origin is not allowed 【发布时间】:2013-07-16 19:26:49 【问题描述】:我在获取跨域 POST 请求以访问最新 beta 2 版本中的 Api 控制器时遇到了很多麻烦。
Chrome(和其他浏览器)吐槽:
OPTIONS http://api.hybridwebapp.com/api/values 400 (Bad Request)
POST http://api.hybridwebapp.com/api/values 404 (Not Found)
它可能与 this issue 有关,但我已经应用了该解决方法和其他几个修复程序,例如 web.config additions here
我一直在努力解决这个问题,所以我创建了一个解决方案来准确地重现这个问题。
加载网络应用程序会有 2 个按钮,一个用于 GET,一个用于 POST,响应将显示在按钮旁边。 GET 工作。无法让 POST 成功返回。
我可以从 Fiddler 那里得到原因的提示,但这没有任何意义,因为如果您查看响应,它确实在 Access-Controll-Allow-Origin 标头中包含域:
解决方案中有一个名为“ConfigurationScreenshots”的文件夹,其中包含一些 IIS 配置(网站绑定)和项目属性配置的屏幕截图,以便尽可能轻松地帮助我:)
编辑:不要忘记将此条目添加到主机文件 (%SystemRoot%\system32\drivers\etc):
127.0.0.1 hybridwebapp.com api.hybridwebapp.com
**STATUS: ** 似乎某些浏览器(例如 Chrome)允许我继续 POST,而不管 OPTIONS 响应中的错误消息如何(而其他浏览器(例如 Firefox)则不允许)。但我认为这还没有解决。
查看它所拥有的 OPTIONS 请求的 Fidler 截图
访问控制允许来源:http://hybridwebapp.com
还有错误:
来源http://hybridwebapp.com是不允许的
这完全矛盾,就好像它忽略了标题一样。
【问题讨论】:
能否也包含 POST 请求的标头?预检也很奇怪:它在正文中返回一个带有错误消息的 400,但它也返回了正确的 CORS 标头,因此预检成功(正如它后面跟着一个 POST 请求的事实所证明的那样)。跨度> 已添加。感谢您的观看。 我相信您可能会遇到一个已知问题,该问题在测试版后已修复。以下错误评论有修复链接:aspnetwebstack.codeplex.com/workitem/1050 谢谢,是的,看起来这可能是解决方案。我究竟如何应用修复程序,我从来没有这样做过,我总是使用 nuget?我尝试在 VS 中打开源代码,构建,然后引用新编译的 System.Web.Cors.dll 和 System.Web.Http.Cors.dll 但我的应用程序抛出异常:Could not load file or assembly 'System.Web.Cors' or one of its dependencies. Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key.
我建议不要获取最新的夜间版本,因为有一些代码更改可能会破坏你。相反,我建议您创建一个自定义提供程序工厂,它只是具有修复程序的 AttributeBasedPolicyProviderFactory
的副本,然后执行 config.SetCorsPolicyProviderFactory(your-custom-provider-factory-here);
之类的操作...这很可能会解决您的问题..
【参考方案1】:
好的,我已经解决了这个问题。这一定是我遇到过的最奇怪的问题。以下是如何“解决”它:
-
继续像往常一样生活,直到突然无处可去对该域的 OPTIONS 请求开始返回 200 OK(而不是 400 Bad Request)并且 POST 永远不会发生(或者至少看起来没有'不是因为浏览器吞下了它)
意识到 Fiddler 的 OPTIONS 响应神秘地包含“Access-Control-Allow-XXX”的重复项。
尝试从您的 web.config 中删除以下语句,即使您清楚地记得尝试修复之前的问题但它不起作用:
删除这个:
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Access-Control-Allow-Origin" value="http://mydomain.com" />
<add name="Access-Control-Allow-Headers" value="Accept, Content-Type, Origin" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
因为你已经有了这个:
var enableCorsAttribute = new EnableCorsAttribute("http://mydomain.com",
"Origin, Content-Type, Accept",
"GET, PUT, POST, DELETE, OPTIONS");
config.EnableCors(enableCorsAttribute);
道德:你只需要一个。
【讨论】:
对于带有 OWINS 的 Web API,我们可以使用 OAuthAuthorizationServerProvider 来处理预检和实际请求。这应该是根据 Origin 值(如果允许)添加标头的唯一区域,有关详细信息,请参阅本文:ozkary.com/2016/04/web-api-owin-cors-handling-no-access.html 我有一个属性 [AllowCrossSiteJson] 正在做我的 CORS 标头,但是在处理其他事情时,我添加了 OWin.Cors - 你的帖子让我走上了正轨!【参考方案2】:如果您使用 OAuth 授权 。请求不直接转到 web api。您需要为该端点启用 OWIN CORS 支持。
我在我的网站上的表现: 安装 owin cors
Install-Package Microsoft.Owin.Cors
注意:请勿使用:Install-Package Microsoft.AspNet.WebApi.Cors
在文件 Startup.Auth.cs 中
//add this line
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
【讨论】:
为什么不应该使用 Microsoft.AspNet.WebApi.Cors?这两个包有什么区别? 问我明白了,Microsoft.Owin.Cors 是允许所有人使用 cors(webapi,mvc 控制...),WebApi.Cors 只为 WebApi 设置。【参考方案3】:我有一个 MVC 控制器(不是 ApiController),但我提出的解决方案可能对其他人有所帮助。为了允许跨域访问控制器上的 POST 操作 (/data/xlsx
),我实施了 2 个操作:
-
用于飞行前检查
发帖
如果您没有 HttpOptions 操作,那么您会在飞行前检查中得到 404。
代码:
[HttpOptions]
public ActionResult Xlsx()
// Catches and authorises pre-flight requests for /data/xlsx from remote domains
Response.AddHeader("Access-Control-Allow-Origin", "*");
Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
Response.AddHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
return null;
[HttpPost]
public ActionResult Xlsx(string data, string name)
Xlsx(); // Add CORS headers
/* ... implementation here ... */
我已经在 IE 11、Chrome、FireFox 中对其进行了测试。
【讨论】:
投反对票。使用过滤器并使用 MVC/Web Api 的设计方式。不要在操作中添加请求头信息。 更具体地说,我为什么不赞成这个:当你想修改请求/响应管道时使用过滤器。这使您的控制器操作保持干净,并确保整个应用程序中的关注点分离。其次,为什么要在 MVC 中使用 CORS 也是可以讨论的,Web Api 更适合纯内容服务。 MVC 的 CORS 文档受到限制是有原因的。对于 Web Api,请查看 Enable Cors Filter 和 asp.net/web-api/overview/security/… 和 docs.asp.net/en/latest/security/cors.html#setting-up-cors 阅读过滤器,对 AddHeader 方法的每次调用都可以从控制器操作中删除,从而产生完全相同的行为,但控制器更干净。 cors 代码也可以在整个应用程序中重复使用。但是你知道你在做什么,我不会再试图说服你了。有点奇怪,您在论坛上闲逛并且不希望人们给您任何建议?您的答案是 100% 不是 MVC 想要的那样。我不介意你不在乎,但不要在公共论坛上提供它作为答案,因为它对正确的 MVC 开发无效。 这就是我的意思,即使你不关心别人会关心为什么你的解决方案不符合 MVC。我不是在谈论这是否是激活 cors 的方式,但实际代码确实不行。要点:gist.github.com/frederikprijck/22b59541cdab32ac5fdda1a060621587 Http 标头结果:您的解决方案:prntscr.com/bp2k3n,使用过滤器:prntscr.com/bp2k8p 事实上,我什至不确定你的是否可行。据我所知,CORS 请求实际上是 2 个请求——飞行前 OPTIONS 检查和实际请求。您无法在第一个请求中返回 File() 结果并设置了一些Access-Control
标头选项,因此您不能只删除 HttpOptions 方法。【参考方案4】:
将此添加到 ConfigureOAuth 内的 startup.cs 文件中
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
【讨论】:
【参考方案5】:尝试在您的响应标头中添加以下代码:
Response.AddHeader("Access-Control-Allow-Origin", "*");
【讨论】:
@pilau 安全将由 Owin 处理。你会使用令牌等。 @lorddev 从未听说过 Owin。会调查的。谢谢。以上是关于CORS POST 请求不起作用 - 选项(错误请求) - 不允许来源的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot Cors 问题:尝试了所有方法,但 POST 不起作用
即使没有发出预检请求,也会在 POST 请求中出现 CORS 错误