公司項目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");
這個網上有不少示例,這裏就再也不贅述了。