首頁 > web前端 > js教程 > 主體

前端常見跨域解決方案(全)

jacklove
發布: 2018-05-21 16:26:04
原創
1741 人瀏覽過

在學習中經常看見跨域的相關內容,本篇將星界跨域的解決方案。

跨域解決方案
1、 透過jsonp跨域
2、 document.domain iframe跨域
3、 location.hash iframe
4、window.name iframe跨域
5、 postMessage跨域
6、 跨域資源共享(CORS)
7、 nginx代理跨域
8、 nodejs中間件代理跨域
9、 WebSocket協定跨域
一、 透過jsonp跨域
通常為了減輕web伺服器的負載,我們把js、css,img等靜態資源分離到另一台獨立網域的伺服器上,在html頁面中再透過對應的標籤從不同網域下載入靜態資源,而被瀏覽器允許,基於此原理,我們可以透過動態建立script,再請求一個帶參網址實現跨域通訊。
1.)原生實作:

<script> 
  var script = document.createElement(&#39;script&#39;); 
script.type = &#39;text/javascript&#39;; // 传参并指定回调执行函数为onBack script.src = &#39;http://www.domain2.com:8080/login?user=admin&callback=onBack&#39;; document.head.appendChild(script); // 回调执行函数 function onBack(res) {
 alert(JSON.stringify(res)); 
} </script>
登入後複製

服務端傳回如下(返回時即執行全域函數):

onBack({"status": true, "user": "admin"})
2.)jquery ajax:
$.ajax({ url: &#39;http://www.domain2.com:8080/login&#39;, type: &#39;get&#39;, dataType: &#39;jsonp&#39;, // 请求方式为jsonp jsonpCallback: "onBack", // 自定义回调函数名 data: {}});
登入後複製
3.)vue.js:
this.$http.jsonp(&#39;http://www.domain2.com:8080/login&#39;, { params: {}, jsonp: &#39;onBack&#39;}).then((res) => { console.log(res); })
登入後複製

後端node.js程式碼範例:

var querystring = require(&#39;querystring&#39;);var http = require(&#39;http&#39;);var server = http.createServer();
server.on(&#39;request&#39;, function(req, res) {var params = qs.parse(req.url.split(&#39;?&#39;)[1]); 
var fn = params.callback; // jsonp返回设置 res.writeHead(200, { &#39;Content-Type&#39;: &#39;text/javascript&#39; }); 
res.write(fn + &#39;(&#39; + JSON.stringify(params) + &#39;)&#39;); 
res.end();});
server.listen(&#39;8080&#39;);console.log(&#39;Server is running at port 8080...&#39;);
登入後複製

jsonp缺點:只能實作get一種請求。
二、 document.domain iframe跨域
此方案僅限主域相同,子域不同的跨域應用場景。
實作原理:兩個頁面都透過js強制設定document.domain為基礎主域,就實作了同域。
1.)父視窗:(http://www.domain.com/a.html))

<iframe id="iframe" src="http://child.domain.com/b.html"></iframe><script> document.domain = &#39;domain.com&#39;; var user = &#39;admin&#39;;</script>
登入後複製

2.)子視窗:([http://child.domain.com/ b.html)

<script> document.domain = &#39;domain.com&#39;; // 获取父窗口中变量 alert(&#39;get js data from parent ---> &#39; + window.parent.user);</script>
登入後複製

三、 location.hash iframe跨域
實作原理: a欲與b跨域相互通信,透過中間頁c來實現。三個頁面,不同域之間利用iframe的location.hash傳值,相同域之間直接js存取來通訊。
具體實現:A域:a.html -> B域:b.html -> A域:c.html,a與b不同域只能透過hash值單向通信,b與c也不同域也只能單向通信,但c與a同域,所以c可透過parent.parent存取a頁面所有物件。
1.)a.html:([http://www.domain1.com/a.html)]

<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe><script> var iframe = document.getElementById(&#39;iframe&#39;); 
// 向b.html传hash值 setTimeout(function() {
 iframe.src = iframe.src + &#39;#user=admin&#39;; 
}, 1000);
登入後複製

// 開放給同域c.html的回呼方法function onCallback(res ) { alert('data from c.html ---> ' res); }

2.)b.html:(http://www.domain2. com/b.html))