不同頁面通訊與跨域

2022-06-07 04:39:08 字數 4324 閱讀 4424

相信跨域有什麼手段,大家都背得滾瓜爛熟了。現在我們來做一些不在同乙個tab頁面或者跨域的實踐。

localstorage是瀏覽器同域標籤共用的儲存空間,所以可以用來實現多標籤之間的通訊。html5出現了乙個事件: onstorage,我們在window物件上新增監聽就可以監聽到變化:window.addeventlistener('storage', (e) => console.log(e))

需要注意,此事件是非當前頁面對localstorage進行修改時才會觸發,當前頁面修改localstorage不會觸發監聽函式。如果實在是要,自己重寫乙個方法吧,要不就在修改的時候把自己改的內容po上去。

示例: js:

if(!localstorage.getitem('a'))else

window.addeventlistener('storage', (e) => console.log(e))

複製**

我們新建兩個html分別叫1.html和2.html,並加上上面的js,於是我們每次開啟或者重新整理該頁面就會給a加上1。需要注意的是,如果是雙擊開啟,是在file://協議下的,而且不會觸發storage事件,但是會給a加上1,所以可以做乙個功能,計算本地某個檔案被開啟了多少次。如果我們用伺服器開啟,我們的不同tab頁面通訊完成了,而且是實時的。

我們都知道frame可以跨域,那麼我們來試一下。下面例子,都是乙個html內嵌iframe,當然你直接開啟iframe那個檔案,沒什麼意義的

父視窗:1.html

複製**

js:

var originurl = myiframe.location.href

var i = document.queryselector('iframe')

i.onload= function()

複製**

子視窗:2.html

window.onhashchange = function() 

複製**

我們開啟父視窗,發現子視窗的js已經跑起來了。

既然能跨域,我們直接雙擊開啟1.html,發現還是可以,這個例子雙擊開啟和伺服器開啟都能達到目的

父調子:還是基於前面的條件

var i = document.queryselector('iframe')

i.onload= function()

複製**

子:2.html

function f()

複製**

子調父: 子:2.html

parent.fn1()

複製**

父:1.html

function fn1(s)

}複製**

當然,你直接開啟2.html是沒意義的而且是報錯:uncaught typeerror: parent.fn1 is not a function這個需要注意,不能跨域,所以雙擊開啟以及不同域是報錯的:uncaught domexception: blocked a frame with origin "null" from accessing a cross-origin frame.,只能伺服器開啟

類似於vue、react的prop父子傳值,只要在父視窗設定iframe標籤的name,在子視窗就可以讀到。

父視窗:1.html

複製**

子視窗:2.html

console.log(window.name)

複製**

少年,放心地雙擊開啟吧,有效果的。

h5之後為window新增了window.postmessage()方法,第乙個引數是要傳送的資料,第二個引數是網域名稱。

父視窗:1.html

複製**

子視窗:2.html

window.onmessage = function (e) 

複製**

可以跨域,所以能直接雙擊開啟可以看見效果。

上面的父子視窗,是指乙個html裡面的iframe標籤引入另乙個html。

也就是兩個毫無關係的tab頁面通訊(比如我開啟乙個baidu和乙個github),怎麼通?

當然baidu和github能不能通訊,我們不知道,得問他們家的開發。前面我們已經知道,iframe能跨域,localstorage能使得兩個tab頁面通訊。那我們就來試一下,iframe橋接兩個互不相干的tab頁面。注意,bridge是乙個html,其他兩個tab是指瀏覽器開啟的兩個html檔案。你可以另外建立兩個不同的html,也可以建立兩個一模一樣的html,然後雙擊開啟也好、伺服器開啟也好,有兩個就可以了。

下面,我們把橋接的iframe叫做bridge.html吧。我們用node開啟,監聽本地的1000埠。

head>

hih1>

body>

window.addeventlistener("storage", function(ev)

});window.addeventlistener('message',function(e));

script>

html>

複製**

我們再來兩個頁面,內容如下。接著我們可以以n種不同方式分別開啟,反正是非同源就可以了

title>

head>

subbutton>

p>

iframe>

body>

var ipt = document.queryselector('#ipt')

function sub()

window.addeventlistener('message',function(e));

script>

html>

複製**

然後乙個簡單的聊天就搞定了,試試看。加上websocket的話,還可以非同源聊天呢,其他的可以自己隨意設定了。

從1到2的資訊實時傳遞更新就這樣子成功了,反之亦然。

顧名思義,資訊通道。允許我們建立乙個新的訊息通道,並通過它的兩個messageport 屬性傳送資料m,而且在 web worker 中可用。可以控制台列印,發現有兩個屬性,portl1和port2。乙個頁面內嵌與iframe最常用這種方法。

就像一條管道,一邊出一邊進,我們可以給postmessage方法加上第三個引數:

var channel = new messagechannel();

channel.port1.addeventlistener("message", function(e));

複製**

n種不同的物件型別?環引用?怎麼做到特別容易的深拷?

然而真的做到了:

var obj =]},h:null}

obj.h = obj

var res

new promise(resolve => ).then(data=>)

複製**

傳了資料給管道,管道傳回來乙個長得一模一樣的資料回來,實現了深拷貝。我們叫他結構化轉殖,能處理物件迴圈依賴和大部分的內建物件。比如postmessage發訊息給子視窗或者webworker的時候就會經常用到,拿到資料進行處理,但不汙染原資料。

web不同頁面通訊 安全跨域通訊

在子頁面向父頁面傳送訊息,使用 parent.postmessage 在父頁面向子頁面傳送訊息,使用 window.frames index postmessage data 傳送的資料 origin 傳送的源 bool 可選 false 事件冒泡 true 事件捕獲 window.postmess...

父子頁面跨域通訊

該window.postmessage 方法安全地啟用window物件之間的跨源通訊 例如,在頁面和它產生的彈出視窗之間,或者在頁面和嵌入其中的iframe之間。targetwindow.postmessage message,targetorigin,transfer 要傳送到其他視窗的資料。使用...

iframe跨域父子頁面通訊方法

儘管iframe因相容 效能等問題逐漸被替換掉,但有不少存量專案仍在使用。最近,我們部門一位小夥伴遇到iframe跨域相關問題,詳細如下 問題前置條件 有兩個系統a b 都是銀行存量老系統 a b跨域 a系統中有乙個頁面a b系統中有乙個頁面b b以iframe方式嵌在a頁面中。問題描述 那麼,if...