摘要:常用跨域方法總結為什么要跨域因為瀏覽器的一種安全機制同源策略的限制,導致不能直接獲取不同源的資源,所以要跨域。那么什么才叫同源呢協議相同域名相同端口號相同圖來自參見最后下面介紹常用的幾種跨域方法。
常用跨域方法總結 為什么要跨域?
因為瀏覽器的一種安全機制——同源策略的限制,導致不能直接獲取不同源的資源,所以要跨域。
同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用于隔離潛在惡意文件的重要安全機制。
限制之一是不能通過ajax的方法去請求不同源中的文檔。
第二個限制是瀏覽器中不同域的框架(iframe)之間是不能進行js的交互操作的。
那么什么才叫“同源”呢?
協議相同
域名相同
端口號相同
圖來自MDN,參見最后Reference.
下面介紹常用的幾種跨域方法。
jsonp 跨域原理:
利用了標簽不受瀏覽器同源限制的影響,
因為借用發起的請求,所以會把請求到的內容當作js代碼來解析執行。
缺點:只能發送get請求
下面是一個簡單的例子
Title
如上,定義了一個全局的callback 函數,然后利用來發起get請求,注意把函數名稱callback 一同發送給服務端,為什么呢,接著往下看服務端代碼
//nodeJs var http = require("http"); var url = require("url"); /** * 客戶端請求的函數 * @param req * @param res */ function onRequest (req, res) { console.log("獲取到的請求參數的路徑:" + req.url); //得到鍵值對 var arg = url.parse(req.url, true).query; //打印鍵值對中的值 console.log(arg.cb); res.writeHead(200); res.write(arg.cb + "("我今天要用jsonp來跨域獲取數據")"); res.end(); } http.createServer(onRequest).listen(8080);
服務端簡單解析cb參數(我們傳的函數名稱),然后返回一段字符串callback("我今天要用jsonp來跨域獲取數據")
瀏覽器會收到響應如下:
發現什么了嗎?響應內容callback("我今天要用jsonp來跨域獲取數據")會被當作js代碼來執行,正好調用了我們之前定義的callback函數。
由此,我們成功的利用jsonp通過跨域獲取到了想要的數據。
開頭我們說到不同源的框架之間是不能進行js交互操作的,其實是可以獲取window對象,但不能獲取window的屬性。
原理:
document.domain的值是可以設置的,但僅限于設置為自身或是更高一級的父級域名(主域名相同)。
那么主域名相同,子域名不同的框架之間跨域獲取數據的思路就來了,我們把它們的document.domain都設置成主域名不就完事了?
比如有一個頁面a.google.com/1.html
這里參考了其他文章的代碼。出處見本文最下方
另一個頁面b.google.com/2.html只需設置主域名為google.com,兩個框架間就可以進行交互啦。
location.hash跨域(不同源的框架之間)原理:
hash字段(經常用于錨點定位)不屬于http協議的部分,請求不會攜帶hash信息,所以改變不會重新請求資源(但是會產生新的瀏覽器歷史記錄,許多前端路由也是借用這個原理實現的)
父窗口可以對iframe進行URL讀寫,iframe也可以讀寫父窗口的URL(不同源的話,IE、Chrome不允許修改parent.location.hash的值,但我們仍有處理方式)
思路:
如果是父窗口向子窗口跨域傳遞數據,直接修改子窗口url的hash就可以了,比較簡單這里就不貼代碼了。
子窗口向父親窗口跨域傳遞數據就需要多加一個代理窗口(因為IE,Chrome),這個代理窗口和父親窗口同源就可以了,在這個代理窗口改變父親窗口的hash,父親窗口監聽hashchange就可以了。
代碼如下:
父親窗口頁面
http://localhost:63342/test-field/cross-origin/local-test/hash-parent.html
Title
子窗口頁面
http://blank121.github.io/tes...
try{ parent.location.hash="今天我要用hash跨域" //chrome ie 直接修改parent.location.hash報錯 }catch (e){ var iframe = document.createElement("iframe") iframe.src = "https://localhost:63342/test-field/cross-origin/local-test/hash-proxy.html"+"#今天我要用hash跨域" document.body.appendChild(iframe); }
代理窗口頁面
http://localhost:63342/test-field/cross-origin/local-test/hash-proxy.html
Title
如上,在子窗口頁面內修改了代理窗口的hash值,代理窗口又修改了父親窗口的hash值,父親窗口監聽hashchange就可以獲取到不同源的子窗口傳來的數據啦。
控制臺結果如下:
原理:
window對象有個name屬性,該屬性有個特征:即在一個窗口(window)的生命周期內,窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的所有頁面中的,并不會因新頁面的載入而進行重置。
利用一個窗口的生命周期內,載入不同頁面window.name不變的特性
貼代碼前首先去做個有趣的實驗
在必應的首頁設置一下window.name
然后輸入location.href = "http://www.baidu.com",跳轉到百度后再看一下name
666,window.name果然沒騙我,沒有變化。
接下來先貼代碼
父親窗口:
http://localhost:63342/test-field/cross-origin/local-test/name-parent.html
Title
子窗口:
https://blank121.github.io/te...
window.name跨域
代理窗口(啥也沒做。主要是要和父親窗口同源來傳遞name)
Title
代碼如上,主要思路就是利用window.name不變性,子窗口設置了name之后,來加載一個和父親窗口同源的代理窗口,以此來獲取name(注意子窗口和代理窗口是同一個iframe,加載不同頁面而已,所以window.name不變)
postMessage跨域首先了解一下postMessage
otherWindow.postMessage(message, targetOrigin);
otherWindow:指目標窗口,也就是給哪個window發消息,是 window.frames 屬性的成員或者由 window.open 方法創建的窗口
message: 是要發送的消息,類型為 String、Object (IE8、9 不支持)
targetOrigin: 是限定消息接收范圍,不限制請使用 *
postMessage是HTML5新特性,跨域簡直太方便了,就是兼容性要注意一下。
發送方頁面
Title
接收方頁面
Title
接收方監聽一下message事件,就可以接收到信息啦。
WebSocket跨域WebSocket 是一種在客戶端與服務器之間保持TCP長連接的網絡協議,這樣它們就可以隨時進行信息交換(雙工通訊)。
雖然任何客戶端或服務器上的應用都可以使用WebSocket,但原則上還是指瀏覽器與服務器之間使用。通過WebSocket,服務器可以直接向客戶端發送數據,而無須客戶端周期性的請求服務器,以動態更新數據內容。
WebSocket 非常強大,筆者在這方面也是小白級別的,以后有時間會詳細研究學習。
跨域代碼如下
頁面:
Title
服務端nodeJs代碼:
var WebSocketServer = require("ws").Server; var wss = new WebSocketServer({ port: 8080 }); wss.on("connection", function connection(ws) { ws.on("message", function incoming(message) { console.log("received: %s", message); ws.send("hello"+message); }); });
結果如圖:
瀏覽器端:
服務端:
完美實現了跨域。
CORS(cross origin resource sharing 最常用)老生常談的CORS,優秀的文章已經非常多了,大家可以搜一下,非常重要,有機會我會專門寫一篇文章來學習總結,在此就不再詳述了
最后不得不說,這些方法還是比較巧妙的,在此寫下一篇文章來總結一下,感覺自己面對跨域絲毫不慌啦。
Reference前端跨域整理
正確面對跨域,別慌
瀏覽器的同源策略
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/52532.html
摘要:常用跨域方法總結為什么要跨域因為瀏覽器的一種安全機制同源策略的限制,導致不能直接獲取不同源的資源,所以要跨域。那么什么才叫同源呢協議相同域名相同端口號相同圖來自參見最后下面介紹常用的幾種跨域方法。 常用跨域方法總結 為什么要跨域? 因為瀏覽器的一種安全機制——同源策略的限制,導致不能直接獲取不同源的資源,所以要跨域。 同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行...
摘要:常用跨域方法總結上篇文章介紹了幾種常用的跨域方法常用跨域方法總結,本片為上一篇的補充,對比較重要的詳細介紹。出于安全原因,從腳本內發起的跨源請求會受到一定限制。當開發者使用對象發起跨域請求時,它們已經被設置就緒。 常用跨域方法總結(2)——CORS 上篇文章介紹了幾種常用的跨域方法:常用跨域方法總結,本片為上一篇的補充,對比較重要的Cross Origin Resource Shari...
摘要:常用跨域方法總結上篇文章介紹了幾種常用的跨域方法常用跨域方法總結,本片為上一篇的補充,對比較重要的詳細介紹。出于安全原因,從腳本內發起的跨源請求會受到一定限制。當開發者使用對象發起跨域請求時,它們已經被設置就緒。 常用跨域方法總結(2)——CORS 上篇文章介紹了幾種常用的跨域方法:常用跨域方法總結,本片為上一篇的補充,對比較重要的Cross Origin Resource Shari...
閱讀 1810·2021-08-13 15:06
閱讀 3100·2021-08-05 10:02
閱讀 3365·2019-08-30 15:55
閱讀 2378·2019-08-30 13:46
閱讀 2485·2019-08-30 13:01
閱讀 1323·2019-08-29 17:17
閱讀 2824·2019-08-29 15:27
閱讀 1431·2019-08-29 11:12