跨域請求CORS

預(yù)備知識:

  1. 只有瀏覽器才會有跨域請求限制涩赢,也就是如果是服務(wù)器之間直接發(fā)起http請求不會存在該限制湃窍。
  2. CORS是在不滿足同源策略的情況下辙售,才有可能引起跨域請求限制材失。
  3. 同源策略校驗包括protocol + host/domain + port(80/443會省略),只有三者完全相同是瘸恼,才滿足同源策略愁拭。
  4. <script><img><iframe><link><video><audio>帶有src屬性褪贵,瀏覽器允許跨域請求
  5. 表單提交时捌、重定向允許跨域?qū)懖僮鳎ù藭r可能引起CSRF怒医,可以通過埋token的方式避免)
  6. 瀏覽器不支持跨站點(diǎn)訪問Cookie、LocalStorage匣椰、IndexDB
  7. 瀏覽器不支持跨站點(diǎn)訪問DOM
  8. 瀏覽器不支持跨站點(diǎn)的AJAX請求裆熙,在不進(jìn)行跨域請求配置的情況下。

跨域請求的解決方案:

  • 簡單請求

    • 請求method只能是GET/POST/HEAD
    • 僅能使用CORS安全的Header: Accept禽笑、Accept-Language入录、Content-Language、Content-Type
    • Content-Tytpe只能是如下的一種:text/plain佳镜、multipart/form-data僚稿、applicaton/x-www-form-urlencoded
    • 請求中必須攜帶Origin頭部,服務(wù)端通過響應(yīng)Access-Control-Allow-Origin頭部來只是瀏覽器該如何處理該請求(如果Access-Control-Allow-Origin為Origin的值或者為*時蟀伸,瀏覽器才允許渲染請求結(jié)果)
  • 復(fù)雜請求

請求示例:

  1. 創(chuàng)建html文件蚀同,內(nèi)部含有Ajax請求(http://127.0.0.1:8081和http://127.0.0.1:8082不滿足同源策略)
<html>
<body>
    <p>跨域請求測試</p>
    <p id="resp"></p>
    <script>
        var invocation = new XMLHttpRequest();
        var url = "http://127.0.0.1:8082";

        function handler() {
            if (invocation.readyState == 4) {
                if (invocation.status==200) {
                    console.log(invocation.responseText);
                    document.getElementById('resp').innerHTML=invocation.responseText;
                }
            }
        }

        function callOtherDomain() {
            if (invocation) {
                invocation.open('GET', url, true);
                invocation.onreadystatechange = handler;
                invocation.send();
            }
        }

        callOtherDomain();
    </script>
</body>
</html>%
```html

2. 配置nginx server
server {
    listen      8081;
    server_name localhost;
    charset     utf-8;

    location / {
        # 這個地方需要修改成你上面保存的cors.html的目錄
        root /path-to-directory;
        index cors.html cors.htm;
    }
}

server {
    listen      8082;
    server_name localhost;
    charset     utf-8;

    location / {
        return 200 'hello world';
    }
}

保存,執(zhí)行nginx -s reload

  1. 打開瀏覽器啊掏,訪問http://127.0.0.1:8081蠢络。你將會發(fā)現(xiàn)http://127.0.0.1:8082的Ajax請求失敗了,瀏覽器提示CORS error(MissingAllowOriginHeader) 迟蜜。
    但是通過抓包可以看到刹孔,nginx其實將相應(yīng)('hello world')返回給瀏覽器了,但是由于不滿足CORS policy,相應(yīng)被瀏覽器隱藏了娜睛。抓包截圖:


    image.png

3.1 修改8082站點(diǎn)的配置髓霞,以允許來自8081的跨站請求

    server {
        listen      8082;
        server_name localhost;
        charset     utf-8;

        location / {
            add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
            return 200 'hello world';
        }
    }

再次刷新瀏覽器,可以發(fā)現(xiàn)請求正常返回了
因為Response header中返回了Access-Control-Allow-Origin: http://127.0.0.1:8081

4. 更多的跨域請求響應(yīng)Header

image.png

5. 常見錯誤

5.1 MultipleAllowOriginValues

Access to XMLHttpRequest at 'http://127.0.0.1:8082/' from origin 'http://127.0.0.1:8081' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 'http://127.0.0.1:8081, http://127.0.0.1:8083', but only one is allowed.

原因:response header中返回了多個AccessControlAllowOrigin值(可以是相同的畦戒,也可以是不同的)方库。例如如下的服務(wù)端返回:

    server {
        listen      8082;
        server_name localhost;
        charset     utf-8;

        location / {
            add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
            add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
            return 200 'hello world';
        }
    }

Access-Control-Allow-Origin只能返回一個源

add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081';
add_header Access-Control-Allow-Origin 'http://127.0.0.1:8083';
這種不同的源也是不行的,即使相同的源也是不行的。
add_header Access-Control-Allow-Origin 'http://127.0.0.1:8081,http://127.0.0.1:8083';
這種也是不行的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末障斋,一起剝皮案震驚了整個濱河市纵潦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垃环,老刑警劉巖邀层,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異晴裹,居然都是意外死亡被济,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門涧团,熙熙樓的掌柜王于貴愁眉苦臉地迎上來只磷,“玉大人,你說我怎么就攤上這事泌绣∨プ罚” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵阿迈,是天一觀的道長元媚。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么刊棕? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任炭晒,我火速辦了婚禮,結(jié)果婚禮上甥角,老公的妹妹穿的比我還像新娘网严。我一直安慰自己,他們只是感情好嗤无,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布震束。 她就那樣靜靜地躺著,像睡著了一般当犯。 火紅的嫁衣襯著肌膚如雪垢村。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天嚎卫,我揣著相機(jī)與錄音嘉栓,去河邊找鬼。 笑死驰凛,一個胖子當(dāng)著我的面吹牛胸懈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播恰响,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼趣钱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胚宦?” 一聲冷哼從身側(cè)響起首有,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枢劝,沒想到半個月后井联,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡您旁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年烙常,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹤盒。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚕脏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侦锯,到底是詐尸還是另有隱情驼鞭,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布尺碰,位于F島的核電站挣棕,受9級特大地震影響译隘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜洛心,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一固耘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧皂甘,春花似錦玻驻、人聲如沸悼凑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽户辫。三九已至渐夸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渔欢,已是汗流浹背墓塌。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奥额,地道東北人苫幢。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像垫挨,于是被迫代替她去往敵國和親韩肝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容