html中跨页面通讯方式,跨文档通信的7种方法

摘要

以下总结的跨文档通信方法,均是在服务器不参与的情况下(服务端无需特殊的代码)实现的

这里的通信,是指页面A向页面B传递信息

大致分为以下三类

通过 window.postMessage 实现双向通信

通过客户端存储实现通信

cookie

webStorage

indexedDB

在页面跳转的过程中携带信息

window.name

Url 中 hash

window.history.replace() && document.referrer

其中第一种方法没有跨域的限制,且实现的是双向通信;第二种方法本质上利用的是同源文档可以访问同一块数据实现通信;第三种方法只能实现定向的单次的通信,且没有跨域的限制

通过 window.postMessage 实现通信

搭建服务端

const http = require('http')

const fs = require('fs')

http.createServer((req, res) => {

fs.readFile(`.${req.url}`, (err, data) => res.end(data))

}).listen(8888)

编写文档 index1.html

...

index1

new Window

Send Message

const newWBtn = document.getElementById('newWindow')

const sendBtn = document.getElementById('sendMessage')

let newWindow = null

newWBtn.addEventListener('click', () => {

newWindow = window.open(`${document.origin}/index2.html`)

})

sendBtn.addEventListener('click', () => {

newWindow.postMessage('messageFromIndex1', document.origin)

})

window.addEventListener('message', e => console.log(e.data), false)

...

编写文档 index2.html

...

index2

window.addEventListener('message', receiveMessage, false)

function receiveMessage(event){

console.log(event.data)

event.source.postMessage('messageFromIndex2', event.origin)

}

...

以上代码实现了通过 index1.html,新建窗口 index2.html

index1.html 向 index2.html 发送消息 messageFromIndex1

index2.html 收到来自 index1.html 的消息,并返回消息 meesageFromIndex2

index1.html 和 index2.html 互相传递消息的过程并不需要服务端参与

测试过程

启动服务器 node server.js

访问 http://localhost:8888/index1.html

先后点击 new Window 和 send Message,可以看到在 index1.html 和 index2.html 的控制台中分别出现了 messageFromIndex2 和 messageFromIndex1

补充

通过 postMessage 可以实现跨域的信息传递,因此也要注意传递信息的过程中要检查信息的安全性

通过客户端存储手段实现通信

将需要传递的信息保存在客户端中,只有同源的文档才能访问,具体的实现方式有

cookie

webStorage

IndexedDB

通过设置 cookie 进行通信

当服务端没有设置 cookie 为 HttpOnly 时,可以在浏览器端设置和访问 cookie,而 cookie 本质上是服务器发送到用户浏览器并保存在浏览器上的一块数据,同源的文档可以访问 cookie

修改 index1.html

...

index1

new Tab

const newWBtn = document.getElementById('newWindow')

newWBtn.addEventListener('click', () => {

document.cookie = 'name=test'

window.open(`${document.origin}/index2.html`)

})

...

修改 index2.html

...

index2

console.log(document.cookie)

...

可以看到在 index2.html 的控制台中打印出了信息 'name=test'

通过 cookie 进行跨文档通信,就像同源文档访问同一个对象

通过 webStorage 进行通信

webStorage 就像一个数据库,同源的文档访问同一个子数据库

具体操作方法如下

window.localStorage.setItem(key, value)

window.localStorage.getItem(key)

通过 indexedDB 进行通信

indexedDB 就是一个数据库

修改 index1.html

...

index1

index2.html

add Data

print Data

let request = window.indexedDB.open('mydb', 2)

let time = 1

/* 创建objectStore和修改objectStore都只能在db的onupgradeneeded事件中进行 */

request.onupgradeneeded = e => {

let db = e.target.result

if (!db.objectStoreNames.contains('mystore')) {

let objectStore = db.createObjectStore('mystore', {

keyPath: 'id'

})

objectStore.createIndex('id', 'id', {

unique: true

})

}

}

const addBtn = document.getElementById('addBtn')

const printBtn = document.getElementById('printBtn')

addBtn.addEventListener('click', () => {

// 打开数据库

let request = window.indexedDB.open('mydb', 2)

request.onsuccess = e => {

// 打开数据库 获得db

let db = e.target.result

let transaction = db.transaction(['mystore'], 'readwrite')

// 获得 objectStore 相当于数据库中的表

let objectStore = transaction.objectStore('mystore')

// 向表中添加字段

objectStore.put({

id: '100002',

name: `time_${time++}`,

})

}

})

printBtn.addEventListener('click', () => {

// 打开数据库

let request = window.indexedDB.open('mydb', 2)

request.onsuccess = e => {

// 打开数据库 获得db

let db = e.target.result

let transaction = db.transaction(['mystore'], 'readonly')

// 获得 objectStore 相当于数据库中的表

let objectStore = transaction.objectStore('mystore')

// 向表中添加字段

objectStore.get('100002').onsuccess = e => console.log(e.target.result)

}

})

...

修改 index2.html

...

index2

print Data

const printBtn = document.getElementById('printBtn')

printBtn.addEventListener('click', () => {

// 打开数据库

let request = window.indexedDB.open('mydb', 2)

request.onsuccess = e => {

// 打开数据库 获得db

let db = e.target.result

let transaction = db.transaction(['mystore'], 'readonly')

// 获得 objectStore 相当于数据库中的表

let objectStore = transaction.objectStore('mystore')

// 向表中添加字段

objectStore.get('100002').onsuccess = e => console.log(e.target.result)

}

})

...

如此实现在 index1.html 中修改 indexedDB 中存储的数据时,index2.html 中也可以访问到,以此来间接实现通信

页面跳转的过程中携带信息

以下这些方法都没有域的限制,但对跳转到新页面的方式有限制

通过 window.name 进行通信

设置 window.name = message

当通过 window.location.href 或 index2.html 在当前窗口载入新页面时,window.name 仍保存着上个页面所设置的信息

修改 index1.html

...

index1

index2.html

window.name = 'messageFromIndex1'

...

修改 index2.html

...

index2

console.log(window.name)

...

会在控制台输出 messageFromIndex1

通过在 url 中添加 hash 字段

修改目标文档的 url,将想要传递的信息保存在 url 的 hash 字段中

通过 window.history.replace() 和 document.referrer

设置 window.history.replaceState(window.history,state, document.title, 'message')

从该页面到新页面后,通过 document.referrer 就可以看到来自上个页面的信息

修改 index1.html

...

index1

index2.html

window.history.replaceState(window.history.state, document.title, 'messageFromIndex1')

...

修改 index2.html

...

index2

console.log(document.referrer)

...

会在控制台输出 http://localhost:8888/messageFromIndex1

这里利用的是 window.history.replaceState() 修改 url,并不会使页面重新加载,所以将信息存在 url 中

document.referrer 会保存返回跳转或打开到当前页面的那个页面的 url

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值