我已经彻底搜索过,但在我的特定情况下找不到解决这个问题的方法。
使用Fiddler(POST)的跨域服务调用正确执行并接收数据。但是,通过浏览器(Chrome),我收到消息“预检有无效的HTTP状态代码404”
我有一个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>
这是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 );
}
});
显然,完全在同一个域上工作,如上所述,它可以使用Fiddler。
我确定浏览器的预检OPTIONS检查对于'application / json'的内容类型失败但我不确定如何修复它。
我应该添加web.config文件中的某些内容吗?
我尝试删除'内容类型'而没有任何影响。
我原本希望this article能解决问题(看起来很有希望),但遇到同样的错误:
XMLHttpRequest cannot load [URL]. Response for preflight has invalid HTTP status code 404
答案 0 :(得分:37)
在上面的配置更改后,感谢但是得到了405错误。
最后,在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();
}
}
答案 1 :(得分:15)
我终于开始工作了。
这篇文章“WebAPI with CORS – IIS Intercepts OPTIONS Verb”告诉我的想法。图像显示在IIS中,OPTIONS处理程序映射出现的原因以及为什么在web.config中我们需要删除它以确保IIS不会拦截。
当我看一下IIS那个处理程序不在那里时。然后,我查看了链接文章“Can't set HttpHandler order using Web.Config unless a «clear» tag exists”,并在本文中看到,在删除OPTION处理程序后,它在web.config中显式添加。
由于我在IIS中看不到OPTION处理程序,我也将它添加到web.config文件中,所有这些都突然起作用了。似乎这种添加是需要的。
最终的web.config处理程序部分如下所示(注意我决定保留最初的'remove',以防万一我将来迁移到另一个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>
答案 2 :(得分:11)
这对我有用。
在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();
}
}
在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>
重建并嘿presto。
答案 3 :(得分:2)
我有一个类似的设置,显示404错误和500错误,因为我试图在我的Web服务上运行CORS。我的修复程序基本上使用了Hussain的解决方案,但是当我清理我的修复程序时,我注意到只需要一个Response行,并且我能够将原始web处理程序保留在web.config中,并且不需要移动所有的响应处理程序代码。
基本上,我的修复程序在我的ApplicationOnBeginRequest处理程序中包含了 ONE MAJOR FIX :
private void ApplicationOnBeginRequest( object sender, EventArgs eventArgs )
{
...
if ( context.Request.HttpMethod == "OPTIONS" )
response.End();
}
和我的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>
很抱歉,我无法发送此笔记作为对侯赛因答案的评论。
答案 4 :(得分:1)
对于使用.NET Core 3.1的用户,这是一个完整的解决方案(前端到后端):
我的问题:当我在Web API上启用Windows身份验证时,无法从我的react应用获取对.NET Core 3.1 Web API的调用,CORS异常了。使用匿名身份验证,它可以工作,但是在启用Windows身份验证时不能。
1.launchSettings.json
这将仅用于您的开发环境,请确保在产品服务器上的IIS中也启用了Windows身份验证。
{
"iisSettings": {
"windowsAuthentication": true,
"anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:58747",
"sslPort": 0
}
},
{... more settings if any}
}
2.Startup.cs:
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。控制器:
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调用示例:
“凭据:'包含'”是秘密
await fetch('http://localhost:3000/Foo/getTest', {
method: 'GET',
credentials: 'include'
}).then(resp => resp.json());
答案 5 :(得分:0)
对于asp核心,请在Configure过程的Startup.cs中使用此代码。我使用的是2.0版本,但我认为它也适用于旧版本
app.UseCors(builder => {
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
答案 6 :(得分:0)
这对我也有帮助,我已经在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();
}
}