深刻跨域問題(1) - 初識 CORS 跨域資源共享

閱讀目錄

深刻跨域問題(1) - 初識 CORS 跨域資源共享(本篇)javascript

深刻跨域問題(2) - 利用 CORS 解決跨域html

深刻跨域問題(3) - 利用 JSONP 解決跨域前端

深刻跨域問題(4) - 利用 代理服務器 解決跨域java

前言

跨域問題,一直困擾咱們很是久,特別是在先後端分離開發條件下,幾乎必定會遇到跨域問題。node

跨域也有不少解決方案:JSONP,iframe,代理,反向代理等。ajax

若是是與後臺一塊兒開發過的小夥伴,確定對這一句感到熟悉:json

Access-Control-Allow-Origin: *
複製代碼

其實,這就已經屬於 CORS 跨域資源共享的內容了,可是,前端和後臺交互的時候仍然存在不少不少問題。後端

這些問題的主要緣由:你和後臺並不熟悉 CORS ,不只後端須要瞭解 CORS ,前端也要很是熟悉 !!!跨域

在這篇文章裏面,我主要闡述 CORS 同源策略,在後續文章中,我會採用 node 模擬出跨域並解決。瀏覽器

產生跨域的條件

瀏覽器安全的基石是 同源策略,什麼是同源策略呢?言簡意賅,就是三個相同:

  • 協議相同。
  • 域名相同。
  • 端口相同。

這三者相同的狀況下,才被稱做 「同源」,同源策略,能夠保證你的服務器的接口是隱私的。

CORS 跨域資源共享就是指,在這個三者 一個或者多個不一樣 的狀況下,容許 跨源 獲取服務器接口的內容。

可是,既然要突破 同源策略 ,那麼 CORS 必須遵照必定 規則 來保證服務器的數據安全。

跨域的例子:

端口不一樣:

假設,你的電腦如今有開啓了兩個服務器,分別在 不一樣的端口

http://localhost:8080/index.html // 發送 ajax 請求

http://localhost:3000 // 提供接口
複製代碼

在這裏,這個服務器並無遵照 同源策略 了,此時,就產生了跨域問題。

協議不一樣:

舉一個很常見的例子,雙擊打開一個 html 文件,你會看到瀏覽器上你會看到:

file:///Users/xxx/Documents/index.html // 客戶端

http://localhost:3000 // 服務器
複製代碼

這就是簡單的 協議不一樣 的跨域例子,這個例子,也是咱們最好實現的例子 。。。

域名不一樣:

這個更明顯了:

https://www.xxx.com/index.html // 客戶端

https://www.yyy.com // 服務器
複製代碼

這個例子,我想不用過多解釋了吧。

CORS 資源共享

我想,大多數人在看 MDN 文檔上面的解釋時,也會一臉懵逼吧,感受頗有道理的樣子但不知道該怎麼用。

說白了,CORS 只是在 HTTP 協議內部,新增了若干個 首部字段 ,來制定 跨域資源共享 的實現 規則

這些首部字段,有哪些呢??? HTTP訪問控制(CORS) MDN 文檔

預請求

此規則規定,處於跨域環境並在下面幾個條件下,瀏覽器會發送兩個請求給服務器;

舉例說明:假設客戶端須要發起 PUT 請求

  1. 首先,客戶端要發送 OPTIONS 請求 給服務器。
  2. 在 服務器內部,須要對 OPTIONS 請求 ,作出一些 設定 ,告訴客戶端 是否容許訪問
  3. 客戶端確認服務器容許該方法,最終發送 PUT 請求;不然,拋出錯誤,服務器拒絕訪問此方法。

這種設定保證了服務器的 安全性,服務器可控制客戶端訪問的內容 !!!

觸發預請求有三種狀況:

  1. 使用了某些方法,好比說 PUT, DELETE 等。
  2. Fetch 規範規定了對 CORS安全的首部字段集合,人爲設置會觸發預請求。
  3. Content-Type的值不是text/plainmultipart/form-dataapplication/x-www-form-urlencoded

因爲篇幅緣由,我並無徹底列出,請查閱 HTTP訪問控制(CORS) MDN文檔。

非預請求:

此規則規定,在跨域產生的條件下,某些請求和方法,不須要預請求,只發送一個請求就好了。

簡單的請求好比說:GET, POST, HEAD 這三個方法。

思考題目:

如今,有一個場景,咱們須要用 ajax 發送一個請求,請問是否可以觸發預請求 ?

例子1:

var data = { name: 'BruceLee', password: '123456' };

$.ajax({
    url: "http://localhost:3000",
    type: "get",
    success: function (result) {
        console.log(result);
    },
    error: function (msg) {
        console.log(msg);
    }
})
複製代碼

例子2:

var data = { name: 'BruceLee', password: '123456' };

$.ajax({
    url: "http://localhost:3000",
    type: "post",
    success: function (result) {
        console.log(result);
    },
    error: function (msg) {
        console.log(msg);
    }
})
複製代碼

例子3:

var data = { name: 'BruceLee', password: '123456' };

$.ajax({
    url: "http://localhost:3000",
    type: "post",
    data: JSON.stringify(data),
    contentType: 'application/json;charset=utf-8',
    success: function (result) {
        console.log(result);
    },
    error: function (msg) {
        console.log(msg);
    }
})
複製代碼

仔細分析上述的三個例子,例子很簡單,做爲前端的你,會對 CORS 擁有新的認知。

參考與鳴謝:

十分感謝上述參考連接的做者,他們的文章是十分有深度和值得多多研讀的。

相關文章
相關標籤/搜索