MVC跨域问题 Response for preflight has invalid HTTP status code 405
公司项目H5调用接口遇到Response for preflight has invalid HTTP status code 405这样的错误,是使用PUT方式提交请求接口。Content-Type设置为application/json,JS代码如下:
$.ajax({
type: "PUT",
url: "http://172.16.200.84:8977/Messages?sessionId=ee876bfbtest",
data:data,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Content-Type", "application/json");
},
success: function (data, textStatus) {
alert(data);
}
});
项目使用的是MVC,而不是WebApi,按照网上的比较通用的方法是直接在MVC项目的webconfig里配置如下节点:
<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" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
</system.webServer>
当然配置后依然没有成功,接下来再试一次还是失败。还是原来的错误。
开始翻墙找各种原因,后来注意到失败的请求Method是OPTIONS,奇怪了,明明是PUT请求,怎么出现了Method为OPTIONS的请求呢?又看到一个外国友人说要在Global.asax里加上如下处理:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.End();
}
}
再试一次,成功了。但是看记录,会有两个请求,一个是OPTIONS请求返回200成功,一个是自己的PUT请求,返回200成功。那么这个OPTIONS请求到底是什么?百度了一下得到了答案:
Preflighted Requests(预检请求)
Preflighted Requests是CORS中一种透明服务器验证机制。预检请求首先需要向另外一个域名的资源发送一个 HTTP OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。
下面的2种情况需要进行预检:
1、简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求;
2、中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等。
原来如此,在js发起PUT请求的时候,头部设置了XMLHttpRequest.setRequestHeader("Content-Type", "application/json"),所以请求的时候会多出一个OPTIONS,如果去掉这个头,就不会多出这次请求了。
当然为了安全起见,可以不配置Web.Config,而是自己定义一个ActionAllowOriginAttribute,继承于ActionFilterAttribute,然后对需要跨域访问的接口加上标签就行了,主要是在header加上如下内容:
response.AddHeader("Access-Control-Allow-Origin", "*");
response.AddHeader("Access-Control-Allow-Methods", "PUT,GET,POST,OPTIONS");
response.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-File-Name");
这个网上有很多示例,这里就不再赘述了。
相关文章
- .NET9在ASP.NET MVC有什么更新?
- ASP.NET MVC与Web Forms的区别
- _ViewStart.cshtml文件的作用
- .NET Core MVC应用程序创建教程
- ASP.NET MVC4/5实现asp-append-version为css/js带上版本号
- ASP.NET Core MVC 添加Area和Route配置
- ASP.NET MVC View视图 .cshtml文件中创建方法
- ASP.NET Core MVC/RazorPage使用Anti-Forgery Tokens进行XSRF/CSRF防护
- AUC is not defined when there is no positive class in the data (Parameter 'PosSample')
- .NET Core MVC判断是否是ajax请求
- .NET MVC ViewBag ViewData Mmodel怎么选择?
- .NET Core MVC 获取UrlReferer
- .NET Core MVC页面输出中文被编码了
- 解释一下MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)模式,并比较它们之间的区别。
- HTTP请求方法(HTTP Request Method)
- vscode C# MVC脚手架
- 使用VSCode开发.NET MVC常用插件
- .NET MVC和Razor Page对比
- IL源码解读,理解MVC里面Filter这个AOP的实现原理
- The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster怎么解决?