在當前項目中,前端通過POST方式訪問后端的REST接口時,發現兩條請求記錄,一條請求的Request Method為Options,另一條請求的Reuest Method為Post。想要解決這個疑惑還得從以下3個概念說起。
Http Options Method
RFC2616標准(現行的HTTP/1.1)中如下描述:
簡而言之,OPTIONS請求方法的主要用途有兩個:
1、獲取服務器支持的HTTP請求方法;
2、用來檢查服務器的性能。
CORS(跨域資源共享)
CORS是一種網絡瀏覽器的技術規范,它為Web服務器定義了一種方式,允許網頁從不同的域訪問其資源。而這種訪問是被同源策略所禁止的。CORS系統定義了一種瀏覽器和服務器交互的方式來確定是否允許跨域請求。
使用CORS的方式非常簡單,但是需要同時對前端和服務器端做相應處理。
1、 前端
客戶端使用XmlHttpRequest發起Ajax請求,當前絕大部分瀏覽器已經支持CORS方式,且主流瀏覽器均提供了對跨域資源共享的支持。
2、 服務器端
如果服務器端未做任何配置,則前端發起Ajax請求后,會得到CORS Access Deny,即跨域訪問被拒絕。
對於C#做如下配置可允許資源的跨域訪問:
<system.webServer>
...
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type" />
<add name="Access-Control-Allow-Methods" value="PUT,GET,POST,DELETE,OPTIONS"/>
</customHeaders>
</httpProtocol>
</system.webServer>
對於nodejs做如下配置可允許資源的跨域訪問:
//設置CORS跨域訪問
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, accept, origin, content-type");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
Access-Control-Allow-Origin:*表示允許任何域發起請求,如果只允許特定的域訪問,則設置Access-Control-Allow-Origin:xxx為具體域名即可。
Preflighted Requests(預檢請求)
Preflighted Requests是CORS中一種透明服務器驗證機制。預檢請求首先需要向另外一個域名的資源發送一個 HTTP OPTIONS 請求頭,其目的就是為了判斷實際發送的請求是否是安全的。
下面的2種情況需要進行預檢:
1、 簡單請求,比如使用Content-Type 為 application/xml 或 text/xml 的 POST 請求;
2、中設置自定義頭,比如 X-JSON、X-MENGXIANHUI 等。
了解完這3個概念,其實答案已經了然了。
參考:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
http://blog.csdn.net/hfahe/article/details/7730944
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS