前言
出於瀏覽器同源策略的影響,瀏覽器會阻止一個域的 js 指令碼和另一個域的內容進行互動,因此產生了跨域問題,該問題也經常在面試和開發中遇到,本文來總結一下相關知識點。
正文
1、什麼是同源策略
因為瀏覽器出於安全考慮,存在同源策略,就是說如果協議、域名、埠號有一個不同就產生了跨域,不同域之間的資源是不能互動的,比如:Ajax 請求別的域的資源就會失敗,無法讀取別的域中網頁的 Cookie 、LocalStorage 和 IndexedDB,無法獲取別的域中網頁中的 DOM 物件等。下面總結了跨域常見的解決方法。
2、跨域解決方法
(1)JSONP 解決跨域
JSONP 是伺服器與客戶端跨源通訊的常用方法。最大特點就是簡單適用,相容性好(相容低版本IE),缺點是隻支援get請求,不支援post請求。
核心思想:網頁通過新增一個<script>元素,向伺服器請求 JSON 資料,伺服器收到請求後,將資料放在一個指定名字的回撥函式的引數位置傳回來。
<script type="text/javascript"> // 建立jsonp 函式 function jsonp(url, data, callback) { var id = "_" + "Json" + (new Date()).getTime(); //建立一個幾乎唯一的id window[id] = function (result) { if (callback) { callback(result); } var getId = document.getElementById(id); //移除Script標籤和id getId.parentNode.removeChild(getId); window[getId] = null; //呼叫函式後進行銷燬 } url = url.replace("callback=?", "callback=" + id); const script = document.createElement('script') script.src = url script.id = id script.async = true script.type = 'text/javascript' document.body.appendChild(script) } // 建立回撥函式 function dosomething(res) { console.log(res.data) } // 呼叫jsonp函式 jsonp('http://test.com/api/getInfo?callback=?', dosomething) </script>
(2)document.domain 解決跨域
瀏覽器通過 document.domain 屬性來判斷兩個頁面是否同源,因此可以設定相同的 document.domain 屬性值來解決跨域,缺點該方法只限於主域相同,子域不同的跨域場景。
// a.html document.domain = "test.com" // b.html document.domain = "test.com"
(3)postMessage Api 解決跨域
通常用於獲取嵌入頁面中的第三方資料,一個頁面傳送訊息,另一個頁面接收訊息,比如通過 iframe 標籤嵌入的父子頁面之間的訊息傳值。
<!-- 父頁面 --> <iframe src="child.html" frameborder="0" id="Iframe"></iframe> <script> // 監聽子頁面傳遞的值 window.addEventListener('message', function (event) { }) // 給子頁面發訊息 document.getElementById('Iframe').contentWindow.postMessage(message, "*") </script> <!-- 子頁面 --> <script> // 子頁面給父頁面發訊息 window.parent.postMessage("給父頁面發訊息", '*') // 監聽父頁面的訊息 window.addEventListener('message', function (event) { }) </script>
(4)CORS 解決跨域
該方式需要服務端和瀏覽器同時支援,瀏覽器會自動進行 CORS 通訊,後端實現了 CORS 就實現了跨域,服務端需要設定 Access-Control-Allow-Origin 就可以開啟 CORS ,該屬性表示哪些域名可以訪問資源,如果使用萬用字元則表示所有網站都可以訪問。
如果要實現帶 Cookie 進行跨域請求,前端需要額外設定 withCredentials 為 true。
(5)Nginx 反向代理
該方法需要通過 Nginx 搭建中轉伺服器,用於轉發請求。只需要在 nginx.config 中配置轉發請求即可。
(6)webpack-dev-server 設定本地代理
該方式用於開發環境中,在webpack.config.js 中設定代理的本地伺服器就可以,如下:
devServer: { port: 8080, proxy: { "/api": { target: "http://192.168.25.20:8088" // 後端介面 } } }
寫在最後
以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長之路會持續更新一些工作中常見的問題和技術點。