由於瀏覽器的 同源策略,在出現 域名、端口、協議有一種不一致時,就會出現跨域,屬於瀏覽器的一種安全限制。
解決跨域問題有很多種方式,常用的就是以下幾種:
jsonp 跨域:動態創建script,再請求一個帶參網址實現跨域通信.缺點就是只能實現 get 一種請求
1 function jsonp(url, jsonpCallback, success) { 2 let script = document.createElement('script') 3 script.src = url 4 script.async = true 5 script.type = 'text/javascript' 6 window[jsonpCallback] = function(data) { 7 success && success(data) 8 } 9 document.body.appendChild(script) 10 } 11 jsonp('http://xxx', 'callback', function(value) { 12 console.log(value) 13 })
document.domain + iframe跨域:兩個頁面都通過js強制設置document.domain為基礎主域,就實現了同域.但是僅限主域相同,子域不同的跨域應用場景
跨域資源共享CORS: 只服務端設置Access-Control-Allow-Origin即可,前端無須設置,若要帶cookie請求:前后端都需要設置 CORS 需要瀏覽器和后端同時支持。IE 8 和 9 需要通過 XDomainRequest 來實現。 瀏覽器會自動進行 CORS 通信,實現 CORS 通信的關鍵是后端。只要后端實現了 CORS,就實現了跨域。 服務端設置 Access-Control-Allow-Origin 就可以開啟 CORS。 該屬性表示哪些域名可以訪問資源,如果設置通配符則表示所有網站都可以訪問資源。
nginx反向代理接口跨域:同源策略是瀏覽器的安全策略,不是HTTP協議的一部分。服務器端調用HTTP接口只是使用HTTP協議,不會執行JS腳本,不需要同源策略,也就不存在跨越問題
postMessage :這種方式通常用於獲取嵌入頁面中的第三方頁面數據。一個頁面發送消息,另一個頁面判斷來源並接收消息
1 // 發送消息端 2 window.parent.postMessage('message', 'http://test.com') 3 // 接收消息端 4 var mc = new MessageChannel() 5 mc.addEventListener('message', event => { 6 var origin = event.origin || event.originalEvent.origin 7 if (origin === 'http://test.com') { 8 console.log('驗證通過') 9 } 10 })
WebSocket協議跨域:
1 var ws = new WebSocket("wss://echo.websocket.org"); 2 ws.onopen = function(evt) { 3 console.log("Connection open ..."); 4 ws.send("Hello WebSockets!"); 5 }; 6 ws.onmessage = function(evt) { 7 console.log( "Received Message: " + evt.data); 8 ws.close(); 9 }; 10 ws.onclose = function(evt) { 11 console.log("Connection closed."); 12 }