標籤:logs webapi prot post webconfig .com content 代碼 提交
調用介面遇到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); }});
嘗試解決
項目使用的是WebApi,按照網上的比較通用的方法是直接在項目的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>…
當然配置後依然沒有成功,接下來再試一次還是失敗。還是原來的錯誤。
繼續努力
後來注意到失敗的請求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,如果去掉這個頭,就不會多出這次請求了。
什麼是CORS
CORS 流程
補充
當然為了安全起見,可以不配置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");
Js 跨域CORS報錯 Response for preflight has invalid HTTP status code 405