Nginx 跨域設(shè)置(CORS)

瀏覽器同源策略

同源策略是Web應(yīng)用程序安全模型中的一個(gè)重要概念。根據(jù)該策略,Web瀏覽器允許第一個(gè)Web頁(yè)面中包含的腳本訪問(wèn)第二個(gè)Web頁(yè)面中的數(shù)據(jù),但前提是兩個(gè)Web頁(yè)面具有相同的源。同源定義為協(xié)議,主機(jī)名和端口號(hào)相同的組合。此策略可防止一個(gè)頁(yè)面上的惡意腳本通過(guò)該頁(yè)面的文檔對(duì)象模型訪問(wèn)另一個(gè)網(wǎng)頁(yè)上的敏感數(shù)據(jù)

AJAX規(guī)避同源策略三種方式

JSONP:介紹可見(jiàn)參考資料;

WebCocket:使用ws://(非加密)和wss://(加密)作為協(xié)議前綴。該協(xié)議不實(shí)行同源政策,只要服務(wù)器支持,就可以通過(guò)它進(jìn)行跨源通信。

CORS(本文重點(diǎn)):跨源資源分享(Cross-Origin Resource Sharing)的縮寫(xiě)。它是W3C標(biāo)準(zhǔn),是跨源AJAX請(qǐng)求的根本解決方法。相比JSONP只能發(fā)GET請(qǐng)求,CORS允許任何類(lèi)型的請(qǐng)求。

Nginx通過(guò)CORS,實(shí)現(xiàn)跨域

Nginx標(biāo)準(zhǔn)配置

server {
    ... ...

        # #設(shè)置跨域配置 Start
        set $cors_origin "";
        if ($http_origin ~* "^http://api.xx.com$"){
                set $cors_origin $http_origin;
        }

        add_header Access-Control-Allow-Origin $cors_origin always; 
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always;
        add_header Access-Control-Allow-Credentials true always;
        add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,x-auth-token always;
        add_header Access-Control-Max-Age 1728000 always;

        # 預(yù)檢請(qǐng)求處理
        if ($request_method = OPTIONS) {
                return 204;
        }
        # #設(shè)置跨域配置 End

    ... ...
}

1.設(shè)置Origin:表示服務(wù)器可以接受的請(qǐng)求

add_header Access-Control-Allow-Origin http://api.baidu.com

表示 http://api.baidu.com 可以請(qǐng)求數(shù)據(jù)。這個(gè)可以設(shè)置為*星號(hào)代表任意跨源請(qǐng)求都支持,但不建議這樣設(shè)置;因?yàn)樵O(shè)置為*星號(hào)將不在支持發(fā)送Cookie。

2.設(shè)置多域名配置

        set $cors_origin "";
        if ($http_origin ~* "^http://api.xx.com$"){
                set $cors_origin $http_origin;
        }
        if ($http_origin ~* "^http://api2.xx.com$"){
                set $cors_origin $http_origin;
        }

這個(gè)寫(xiě)法主要是為了支持多域名設(shè)置,通過(guò)對(duì)請(qǐng)求origin的判斷是否與指定跨域源一致,然后在進(jìn)行header的設(shè)置;

3.設(shè)置跨域支持的請(qǐng)求類(lèi)型

add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always;

4.設(shè)置跨域請(qǐng)求是否允許發(fā)送Cookie,true:支持,false:不支持

add_header Access-Control-Allow-Credentials true always;

5.設(shè)置跨域請(qǐng)求允許的Header頭信息字段,以逗號(hào)分隔的字符串

add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,x-auth-token always;

注:需要特別注意,凡是API中約定了自定義Header,都需要在這里增加,否則不可以跨域請(qǐng)求。

6.本次預(yù)檢請(qǐng)求的有效期,單位為秒,在允許緩存該條請(qǐng)求回應(yīng)1728000秒內(nèi),無(wú)需在發(fā)出一條預(yù)檢請(qǐng)求。

add_header Access-Control-Max-Age 1728000 always;

7.always 參數(shù)的定義

... ... always

Nginx 規(guī)則 add_header默認(rèn)只會(huì)加入到指定response code的請(qǐng)求中;

見(jiàn)官網(wǎng)介紹

Syntax: add_header name value [always];
Default:    —
Context:    http, server, location, if in location


Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0). The value can contain variables.

指定了 always則無(wú)論什么請(qǐng)求都添加header:

If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.

8.預(yù)檢請(qǐng)求處理

        if ($request_method = OPTIONS) {
                return 204;
        }

CORS請(qǐng)求,會(huì)在正式通信之前,增加一次HTTP查詢(xún)請(qǐng)求,稱(chēng)為"預(yù)檢"請(qǐng)求(preflight);瀏覽器先詢(xún)問(wèn)服務(wù)器,當(dāng)前網(wǎng)頁(yè)所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些HTTP動(dòng)詞和頭信息字段。只有得到肯定答復(fù),瀏覽器才會(huì)發(fā)出正式的XMLHttpRequest請(qǐng)求,否則就報(bào)錯(cuò)。

"預(yù)檢"請(qǐng)求用的請(qǐng)求方法是OPTIONS,表示這個(gè)請(qǐng)求是用來(lái)詢(xún)問(wèn)的,因此我們需要在Nginx配置中,針對(duì)預(yù)檢請(qǐng)求進(jìn)行處理,直接返回204 & Response Header,表示服務(wù)器支持允許跨源的訪問(wèn)。

AJAX配置

xhr.withCredentials = false;

CORS請(qǐng)求默認(rèn)不發(fā)送Cookie和HTTP認(rèn)證信息,如果需要支持除了服務(wù)端增加設(shè)置,AJAX請(qǐng)求中打開(kāi)withCredentials屬性。

參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 題目1.什么是同源策略? 同源策略(Same origin Policy): 瀏覽器出于安全方面的考慮,只允許與本...
    FLYSASA閱讀 1,887評(píng)論 0 6
  • 歡迎關(guān)注微信公眾號(hào):全棧工廠 本文主要參考跨域資源共享 CORS 詳解[http://www.ruanyifeng...
    liqingbiubiu閱讀 2,050評(píng)論 0 3
  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對(duì)JavaScript實(shí)...
    Yaoxue9閱讀 1,413評(píng)論 0 6
  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對(duì)JavaScript實(shí)...
    HeroXin閱讀 956評(píng)論 0 4
  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對(duì)JavaScript實(shí)...
    他方l閱讀 1,139評(píng)論 0 2

友情鏈接更多精彩內(nèi)容