公司项目H5调用接口遇到Response for preflight has invalid HTTP status code 405这样的错误,是使用PUT方式提交请求接口。Content-Type设置为application/json,JS代码以下: html
$.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); } });
项目使用的是WebApi,按照网上的比较通用的方法是直接在项目的webconfig里配置以下节点: web
<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> …
固然配置后依然没有成功,接下来再试一次仍是失败。仍是原来的错误。 ajax
后来注意到失败的请求Method是OPTIONS,奇怪了,明明是PUT请求,怎么出现了Method为OPTIONS的请求呢?还要在Global.asax里加上以下处理:json
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种状况须要进行预检: session
一、简单请求,好比使用Content-Type 为 application/xml 或 text/xml 的 POST 请求; app
二、中设置自定义头,好比 X-JSON、X-MENGXIANHUI 等。ui
原来如此,在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");
这个网上有不少示例,这里就再也不赘述了。