1. 程式人生 > >前端開發的跨域問題詳解

前端開發的跨域問題詳解

同源與跨域問題

同源策略: 為了阻止cookie在不同的網站之間傳輸

同源: 協議相同, 域名相同, 埠號相同

兩個頁面的上面三點都相同, 才是同一個網站, 就是同源

http協議的埠號預設是80, 可省

http:  //  www.baidu.com    [:80]   /dir/index.html

協議     域名                       80埠,可省   

跨域問題的產生:

我們寫的前端程式碼是放在一臺網頁伺服器中的, 公司中介面資料是放在另一臺資料伺服器中的,

我們在我們這臺伺服器中訪問介面資料就會產生跨域

(PS 為什麼會產生跨域:

因為兩臺伺服器在網際網路中的域名一定是不一樣的 -->每臺計算機在網路中都有一個唯一的ip標識.

域名不一樣的, 所以一定會跨域)

比方說我們前端程式碼部署在前端伺服器中, 前端html頁面的地址是

我們在這個index.html中傳送ajax請求, 請求地址是另一臺伺服器中的地址

那麼因為域名不同, 所以這兩個頁面不是屬於同一個網站, 造成跨域

所以ajax獲取不到資料

我們現在每次開發時, 程式碼都是放到本地伺服器中的, 所以是同一個伺服器, 所以一直沒有跨域情況產生

jsonp解決跨域問題  --> jsonp的演變

原理:

伺服器端返回一個函式fn(實參), 這個函式一定是帶引數的,前端呼叫這個函式fn(形參), 這樣後臺就把資料傳過來了

原理的原理:

script可以請求跨域的檔案內容,  並將檔案內容當成js程式碼執行

比方說我們在後臺的http://www.baidu.com/json.php檔案中寫上

<?php  echo “alert(666)”?>

然後在本地伺服器中的http://localhost.index.html中引入

這樣開啟index.html檔案, 就可以跨域請求到(訪問到)不是同源網站的json.php檔案, 並將檔案中的程式碼當成js程式碼執行, 就這樣我們就得到伺服器中的資料了

(這裡雖然是php檔案, 但是我們訪問這個php頁面時, 因為伺服器會先執行自己的php檔案中的程式碼, 將結果返回給瀏覽器, 所以我們訪問這個php檔案時, 得到的是alert(666)這個js程式碼)

那麼我們在json.php中echo ”var a = ‘data’”

然後在index.html中console.log(a) 就會打印出data, 實現後臺資料跨域拿到前臺(隱藏點是script引入的js程式碼就是當前頁面中寫的js程式碼了)

優化方法是:

在index.html中定義一個全域性方法

function fn(data) { console.log(data)}

然後我們後臺的json.php中echo “fn(我們想要返回的資料)”

這樣我們在前臺呼叫這個函式的時候, 就能打印出我們想要後端的資料了

這個函式起名字是前端起的, 但是“假”呼叫時在後端, 真呼叫還是在前端

但是這裡還有一個缺點: 後臺得根據前端的這個函式名提前寫死

優化是:

在我們的script中傳入引數

前端中的這個全域性函式名還是得先定下來, 比方叫fn

php.son檔案中 $callback = $_GET[callback]   echo “$callback(‘要傳輸的資料’)”

上面的是jsonp的優化過程, 實際用起來不方便, jquery將jsonp封裝到了ajax方法中

$.ajax({

    datatype: ‘jsonp’  之前預設不寫是json型別, 現在需要跨域, 所以告訴ajax一聲

})

cors解決跨域問題

cross origin resource sharing 跨域資源共享

要求: 瀏覽器ie10+, 伺服器允許跨域

如果公司使用流行框架開發專案的話, 那麼就不用考慮相容問題了, 因為至少ie9+才可以使用流行框架

跨域行為造成瀏覽器中不能拿到資料的原理:

這是瀏覽器自己造成的, 無論你跨不跨域, 只要你訪問伺服器, 伺服器都會給在響應中給你返回資料, 但是瀏覽器會自己判斷自己有沒有做相應的設定,  如果沒有, 就會自動忽略不同源的網站的響應, 報跨域的錯誤.

jsonp對比cors

jsonp沒有相容問題, 但是隻支援get請求, 所以資料大小有限制

cors必須瀏覽器ie10+, 支援所有請求, 資料大小沒有限制

但是兩者都需要伺服器進行允許跨域的設定, 光憑前端沒法跨域, 所以我們前端很快樂啊, 啥都不用做, 就是告訴後臺,得跨域!

跨域問題的終極解決方式 -->反向代理

反向代理也能解決跨域問題, 並且是the most fuking awesome的解決跨域方式, 沒有相容問題, 大小限制

在伺服器中進行相應配置, 前端不需要訪問api.json這個不同源的頁面, 正常訪問網頁伺服器中的某個頁面, 網頁伺服器就會自動將你這個請求, 通過它自己的設定代理訪問資料伺服器中的介面, 拿回資料, 然後再通過網頁伺服器返回給你, 就好像你是在網頁伺服器中拿資料一樣

同樣, 前端啥也不用做,啊哈哈哈...