已启用 CORS,但在 POST JSON 时预检响应具有无效的 HTTP 状态代码 404
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36258959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CORS enabled but response for preflight has invalid HTTP status code 404 when POSTing JSON
提问by ChrisCurrie
I've searched thoroughly but cannot find a solution to this issue in my particular circumstance.
我已经彻底搜索过,但在我的特定情况下找不到解决此问题的方法。
Cross-domain service calls using Fiddler (POST) execute correctly and the data is received. However, through the browser (Chrome) I am getting the message 'preflight has invalid HTTP status code 404'
使用 Fiddler (POST) 的跨域服务调用正确执行并接收数据。但是,通过浏览器(Chrome),我收到消息“预检具有无效的 HTTP 状态代码 404”
I have a Web API application and have installed CORS and ensured the following is present in the web.config file:
我有一个 Web API 应用程序并安装了 CORS 并确保 web.config 文件中存在以下内容:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<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" />
</customHeaders>
</httpProtocol>
</system.webServer>
Here is the Ajax call:
这是 Ajax 调用:
var secretKey = 'difusod7899sdfiertwe08wepifdfsodifyosey',
url = 'http://api.intrinsic.co.uk/api/v1/PTS/ActiveDrivers?api_key=098werolllfWnCbPGAuIXVOJidDHRfYcgxImMlxTXopuekXrSOqOWzEAIdeNTWGPQPpyHxgVGsFysGFKPzq';
jQuery.ajax ({
url: url,
type: "POST",
data: JSON.stringify({ secretKey: secretKey}),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(data){
var content = "<table class=\"container\"><thead><tr><th>Driver Number</th><th>Timestamp</th><th>VRN</th><th>Latitude</th><th>Longitude</th><th>Track Link</th></tr></thead><tbody>";
$.each(data.ActiveDrivers.DriverLocationStatus, function (index, element) {
content += "<tr><td>" + element.DriverNumber + "</td>";
content += "<td>" + dateFormat(element.Timestamp, "d/m/yy") + " " + dateFormat(element.Timestamp, "h:MM TT") + "</td>";
content += "<td>" + element.VRN + "</td>";
content += "<td>" + element.CurrentLatitude + "</td>";
content += "<td>" + element.CurrentLongitude + "</td>";
content += "<td><a href=\"https://www.google.co.uk/maps/place//@" + element.CurrentLatitude + "," + element.CurrentLongitude + ",15z/\" target='_blank'>Track »</a></td></tr>";
});
content += "</tbody></table>";
$( "#result" ).html( content );
}
});
Obviously, works on the same domain perfectly and, as mentioned, it works using Fiddler.
显然,在同一个域上工作得很好,正如前面提到的,它使用 Fiddler 工作。
I'm certain it is the browser's preflight OPTIONS check that is failing for content-type of 'application/json' but I'm not sure how to fix it.
我确定是浏览器的预检选项检查失败了“应用程序/json”的内容类型,但我不确定如何修复它。
Is there something missing in the web.config file that I should add?
我应该添加的 web.config 文件中是否缺少某些内容?
I have tried removing 'content-type' with no affect.
我尝试删除“内容类型”而没有任何影响。
I had hoped this articlewould solve the issue (it seemed promising) but the same error is encountered:
我曾希望这篇文章能解决这个问题(看起来很有希望)但遇到了同样的错误:
XMLHttpRequest cannot load [URL]. Response for preflight has invalid HTTP status code 404
回答by Hussain
Thanks but getting 405 error,after the above config changes.
谢谢,但在上述配置更改后出现 405 错误。
Finally it works after adding below code in web api Global.asax file
最后它在 web api Global.asax 文件中添加以下代码后工作
protected void Application_BeginRequest(Object sender, EventArgs e)
{
//HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
回答by ChrisCurrie
I finally got this to work.
我终于得到了这个工作。
This article 'WebAPI with CORS – IIS Intercepts OPTIONS Verb' informed my thinking. An image showed where, in IIS, the OPTIONS handler mapping appeared and why, within the web.config we needed to remove it to ensure IIS did not intercept.
这篇文章“带有 CORS的WebAPI – IIS 拦截选项动词”告知了我的想法。一张图片显示了 IIS 中出现 OPTIONS 处理程序映射的位置以及为什么在 web.config 中我们需要将其删除以确保 IIS 不会拦截。
When I took a look at IIS that handler WAS NOT there. I then took a look at the linked article 'Can't set HttpHandler order using Web.Config unless a ?clear? tag exists' and saw that, in this article, after removing the OPTION handler, it was then explicitly added within the web.config.
当我查看 IIS 时,该处理程序并不存在。然后我查看了链接的文章“除非 ?clear? 否则无法使用 Web.Config 设置 HttpHandler 顺序?标签存在' 并看到,在本文中,删除 OPTION 处理程序后,它被显式添加到 web.config 中。
As I could not see the OPTION handler in IIS, I too added it to the web.config file and all suddenly worked. It appeared that this addition is what was needed.
由于我在 IIS 中看不到 OPTION 处理程序,所以我也将它添加到 web.config 文件中,然后一切都突然起作用了。看来这个添加是需要的。
The final web.config handlers section looks as follows (notice I decided to keep the initial 'remove' just in case this caused problems if I migrated to a different web server in the future).
最终的 web.config 处理程序部分如下所示(注意,我决定保留最初的“删除”,以防将来迁移到不同的 Web 服务器时会出现问题)。
<system.webServer>
<handlers>
<remove name="WebDAV"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" responseBufferLimit="4194304" />
</handlers>
<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, OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
回答by Darren Street
This worked for me.
这对我有用。
In Global.asax
在 Global.asax
protected void Application_BeginRequest(Object sender, EventArgs e)
{
//HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
In Web.config
在 Web.config 中
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS"/>
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
</customHeaders>
</httpProtocol>
rebuild and hey presto.
重建和嘿presto。
回答by InquisitionX
I have a similar setup that was showing 404 errors and 500 errors as I was attempting to get CORS running on my web service. My fix basically used Hussain's solution, but as I cleaned up my fix, I noted that only one Response line was needed, and I was able to keep the original web handlers in the web.config, and did NOT need to move all of the response handlers into code.
我有一个类似的设置,当我试图让 CORS 在我的 Web 服务上运行时,它显示了 404 错误和 500 错误。我的修复基本上使用了 Hussain 的解决方案,但是当我清理我的修复时,我注意到只需要一个响应行,并且我能够在 web.config 中保留原始 Web 处理程序,并且不需要移动所有响应处理程序转换为代码。
Basically, my fix includes this ONE MAJOR FIXin my ApplicationOnBeginRequest handler:
基本上,我的修复在我的 ApplicationOnBeginRequest 处理程序中包含了这个主要修复:
private void ApplicationOnBeginRequest( object sender, EventArgs eventArgs )
{
...
if ( context.Request.HttpMethod == "OPTIONS" )
response.End();
}
and these handlers in my web.config:
以及我的 web.config 中的这些处理程序:
<system.webServer>
<!--Other handlers/modules ...-->
<httpProtocol>
<customHeaders>
<clear />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Credentials" value="true" />
<add name="Access-Control-Allow-Headers" value="Content-Type,Accept" />
<add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
Sorry I couldn't send this note as a comment to Hussain's answer.
抱歉,我无法将此便条作为对侯赛因回答的评论发送。
回答by Homeslyce
For those using .NET Core 3.1, here is a COMPLETE solution (front-end to back-end):
对于使用 .NET Core 3.1 的用户,这里是一个完整的解决方案(前端到后端):
My problem: When I enabled the windows authentication on my web API, I could not do fetch calls from my react app to my .NET Core 3.1 web API, CORS was freaking out. With Anonymous authentication it worked, but not when windows authentication is enabled.
我的问题:当我在我的 Web API 上启用 Windows 身份验证时,我无法从我的 React 应用程序获取调用到我的 .NET Core 3.1 Web API,CORS 吓坏了。使用匿名身份验证它有效,但在启用 Windows 身份验证时无效。
1.launchSettings.json
1.launchSettings.json
this will be used only for your dev environnment, make sure windows auth is also enabled in IIS on your prod server.
这将仅用于您的开发环境,请确保在您的生产服务器上的 IIS 中也启用了 Windows 身份验证。
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:58747",
"sslPort": 0
}
},
{... more settings if any}
}
2.Startup.cs:
2.Startup.cs:
CORS policy is enabled here. The order of methods is important here. Also, you don't need to set those in a web.config
此处启用 CORS 策略。方法的顺序在这里很重要。此外,您不需要在 web.config 中设置它们
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", //give it the name you want
builder =>
{
builder.WithOrigins( "http://localhost:3000", //dev site
"production web site"
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
//database services here
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
// global policy same name as in the ConfigureServices()
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
3.Controller(s):
3.控制器:
using Microsoft.AspNetCore.Cors;
... your other usings
namespace ProjectTest.Controllers
{
[ApiController]
[EnableCors("CorsPolicy")] //THIS HERE needs to be the same name as set in your startup.cs
[Route("[controller]")]
public class FooController:Controller
{
[HttpGet("getTest")]
public JsonResult GetTest()
{
return Json("bar");
}
}
}
4.React Component fetch call example:
4.React 组件获取调用示例:
The "credential: 'include'" is the secret
“凭证:'包含'”是秘密
await fetch('http://localhost:3000/Foo/getTest', {
method: 'GET',
credentials: 'include'
}).then(resp => resp.json());
回答by valentasm
For asp core use this code in Startup.cs in Configure procedure. I used for 2.0 version but i think it should work with older too
对于 asp 核心,在配置过程中的 Startup.cs 中使用此代码。我用于 2.0 版本,但我认为它也应该适用于较旧的版本
app.UseCors(builder => {
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
回答by Павел Марченко
This helped me too, I had CORS configured in web.config already
这对我也有帮助,我已经在 web.config 中配置了 CORS
protected void Application_BeginRequest(Object sender, EventArgs e)
{
//HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}

