首页 > 其他分享 >浏览器跨页签通信方法

浏览器跨页签通信方法

时间:2024-12-23 09:29:17浏览次数:5  
标签:function 浏览器 log 通信 跨页 let console document 页面

文章目录


一、BroadCast Channel

页面一:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面一</title>
</head>
<body>
<input type="text" name="" id="content">
<button id="btn">发送数据</button>
<script>
    const content = document.querySelector("#content")
    const btn = document.querySelector("#btn")
    //创建一个广播频道
    const broadCastChannel=new BroadcastChannel("load") //对象
    btn.onclick=function (){
        broadCastChannel.postMessage({
            value:content.value
        })
    }
</script>
</body>
</html>

页面二:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面二</title>
</head>
<body>
<script>
    //传入的字符串要和页面一的一样
    const broadCastChannel=new BroadcastChannel("load") //对象
    //监听消息
    broadCastChannel.onmessage=function (e) {
        console.log(e.data.value)
    }
</script>
</body>
</html>

二、Service Worker

service worker实际上是浏览器和服务器之间的代理服务器,它最大的特点是在页面中注册并安装成功后,运行于浏览器后台,不受页面刷新的影响,可以监听和截拦作用域范围内所有页面的http请求。
service worker的目的在于离线缓存,转发请求和网络代理。

页面一:

const content = document.querySelector("#content")
const btn = document.querySelector("#btn")
//注册service worker
navigator.serviceWorker.register('sw.js').then(()=>{
  console.log("注册成功")
})
btn.onclick=function () {
  navigator.serviceWorker.controller.postMessage({
    value:content.value
  })
}

页面二:

//注册service worker
navigator.serviceWorker.register('sw.js').then(()=>{
  console.log("注册成功")
})
navigator.serviceWorker.onmessage=function ({data}){
  console.log(data)
}

sw.js:

//消息就会到达这里
self.addEventListener('message', async event => {
    //获取所有注册了service worker的客户端
    const clients=await self.clients.matchAll();
    clients.forEach(client => {
        client.postMessage(event.data)
    })
})

三、LocalStorage window.onstorage监听

页面一:

    localStorage.age="20"
    localStorage.name="崔"
    localStorage.sex="女"

页面二:

window.onstorage=function (e){
    console.log("测试",e)
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

四、Shared Worker(定时器轮询)

Shared Worker接口代表一种特定类型的worker,可以从几个浏览上下文中访问,例如几个窗口、iframe或其他worker。它们实现一个不同于普通worker的接口,具有不同的全局作用域,如果要使Shared Worker连接到多个不同的页面,这些页面必须是同源的
页面一:

 //创建一个worker
    const worker=new SharedWorker('./worker.js')
    btn.onclick=function(){
        console.log(worker)
        worker.port.postMessage(content.value)
    }

页面二:

  const  worker=new SharedWorker("worker.js")
    worker.port.start()
    worker.port.onmessage=function (e){
        if(e.data){
            console.log("收到的数据",e)
        }
    }
    //轮询
    setInterval(()=>{
        worker.port.postMessage("get")
    },1000)

worker.js:

let data = "" //存储用户发送过来的信息
self.addEventListener("connect", function (e) {
    console.log("进来了")
    let port = e.ports[0];
    port.onmessage = function (e) {
        //将接收到的数据返回给客户端
        if (e.data === 'get') {
            port.postMessage(data)

        } else {
            data = e.data
        }
    }
})

五、IndexedDB定时器轮询

页面一:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面一</title>
</head>
<body>
<h1>新增学生</h1>
<div>
    <span>学生ID:</span>
    <input type="text" name="stuId" id="stuId">
</div>
<div>
    <span>学生姓名:</span>
    <input type="text" name="stuName" id="stuName">
</div>
<div>
    <span>学生年龄名:</span>
    <input type="text" name="stuAge" id="stuAge">
</div>
<button id="addBtn">新增学生</button>
<script src="db.js"></script>
<script>

    let btn = document.querySelector("#addBtn")
    let stuId = document.querySelector("#stuId")
    let stuName = document.querySelector("#stuName")
    let stuAge = document.querySelector("#stuAge")
    openDB("stuDB", 1).then((db) => {
        btn.onclick = function () {
            // deleteDataById(db,"stu",0)
            addData(db, "stu", {
                "stuId": Number(stuId.value),
                "stuName": stuName.value,
                "stuAge": stuAge.value
            })
            stuId.value = stuName.value = stuAge.value = ""
        }
    })
</script>
</body>
</html>

页面二:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面二</title>
    <style>
        table {
            border: 1px solid;
            border-collapse: collapse;
        }

        table td {
            border: 1px solid;
        }
    </style>
</head>
<body>
<table id="tab">


</table>
<script src="db.js"></script>
<script>


    function render(arr) {
        let tab = document.querySelector("#tab")
        tab.innerHTML = `
    <tr>
        <td>学号</td>
        <td>姓名</td>
        <td>年龄</td>
    </tr>
        `
        let str = arr.map(item => {
            return `
                <tr>
        <td>${item.stuId}</td>
        <td>${item.stuName}</td>
        <td>${item.stuAge}</td>
       </tr>
            `
        }).join("")
        tab.innerHTML += str
    }

    async function renderTable() {
        let db = await openDB("stuDB", 1)
        let stuInfo = await getAllData(db, "stu")
        render(stuInfo)
        setInterval(async () => {
            let stuInfo2 = await getAllData(db, "stu")
            if (stuInfo2.length !== stuInfo.length) {
                stuInfo = stuInfo2
                render(stuInfo)
            }
        }, 1000)
    }

    renderTable()

</script>
</body>
</html>

db.js:

/**
 *
 * @param dbName 数据库名称
 * @param version 数据库版本
 */
function openDB(dbName, version = 1) {
  return new Promise((resolve, reject) => {
    let db;//存储数据库对象
    //打开数据库,没有则创建操作
    let request = indexedDB.open(dbName, version)
    //数据库打开或者创建成功的时候
    request.onsuccess = function (event) {
      db = event.target.result;
      console.log("打开成功")
      resolve(db)
    }
    request.onerror = function (res) {
      console.log("打开失败")
    }
    //版本号更新 添加或者删除对象仓库(表)的时候
    //第一次调用open方法的时候会触发这个事件
    //初始化表
    request.onupgradeneeded = function (event) {
      console.log("更新")
      db = event.target.result;
      let objectStore = db.createObjectStore("stu", {
        keyPath: "stuId", //主键
        autoIncrement: true,//自增
      })
      //创建索引 增大查询速度
      objectStore.createIndex("stuId", "stuId", {unique: true})
      objectStore.createIndex("stuName", "stuName", {unique: false})
      objectStore.createIndex("stuAge", "stuAge", {unique: false})
    }
  })
}

/**
 * 关闭数据库
 * @param dbName 数据库名称
 */
function closeDB(dbName) {
  dbName.close()
}

/**
 *删除数据库
 * @param dbName 数据库名称
 */
function deleteDB(dbName) {
  // deleteRequest 操作请求对象
  let deleteRequest = window.indexedDB.deleteDatabase(dbName);
  deleteRequest.onsuccess = function (event) {
    console.log("删除成功")
  }
  deleteRequest.onerror = function (res) {
    console.log("删除失败")
  }
}

/**
 *添加数据
 * @param db 数据库实例
 * @param storeName 数据库仓库实例(表)
 * @param data 要添加的数据
 */
function addData(db, storeName, data) {
  //transaction 事务
  let request = db.transaction([storeName], "readwrite").objectStore(storeName).add(data)
  request.onsuccess = function (event) {
    console.log("写入成功")

  }
  request.onerror = function (res) {
    console.log("写入失败")
  }
}

/**
 * 通过主键读取数据
 * @param db 数据库实例
 * @param storeName 仓库名称
 * @param key 主键
 * @returns {Promise<unknown>}
 */
function getDataByKey(db, storeName, key) {
  return new Promise((resolve, reject) => {
    let transaction = db.transaction([storeName]) //事务
    let objectStore = transaction.objectStore(storeName) //仓库对象
    let request = objectStore.get(key) //通过主键获取数据
    request.onsuccess = function (event) {
      console.log("主键查询结果:", request.result)
      resolve(request.result)
    }
    request.onerror = function (res) {
      console.log("事务失败")
    }

  })
}
/**
 * 获取全部数据
 * @param db 数据库实例
 * @param storeName 仓库名称
 * @returns {Promise<unknown>}
 */
function getAllData(db, storeName) {
  return new Promise((resolve, reject) => {
    let transaction = db.transaction([storeName]) //事务
    let objectStore = transaction.objectStore(storeName) //仓库对象
    let request = objectStore.getAll() //通过主键获取数据
    request.onsuccess = function (event) {
      resolve(request.result)
        }
        request.onerror = function (res) {
            console.log("事务失败")
        }
    })
}


/**
 *通过主键删除数据 (delete方法)
 * @param db
 * @param storeName
 * @param data 数据
 */
function deleteDataById(db, storeName, id) {
    return new Promise((resolve, reject) => {
        let request = db.transaction([storeName], "readwrite").objectStore(storeName).delete(id)
        request.onsuccess = function (event) {
            resolve({
                status: "success",
                message: "删除数据成功"
            })
        }
        request.onerror = function (res) {
            reject({
                status: "error",
                message: "删除数据失败"
            })
        }
    })
}

六、cookie定时器轮询

页面一:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面一</title>
</head>
<body>
<input type="text" name="" id="content">
<button id="btn">发送数据</button>
<script>
  document.cookie="name=小吴"
  console.log("设置成功")
</script>
</body>
</html>

页面二:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面二</title>
</head>
<body>
<script>
 let cookie=document.cookie
 console.log(`当前得cookie值为:${cookie}`)
 setInterval(()=>{
     if(document.cookie!==cookie){
         cookie=document.cookie
         console.log(`最新得值为${document.cookie}`)
     }
 },1000)
</script>
</body>
</html>

七、window.open、window.postMessage

页面一:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面一</title>
</head>
<body>
<button id="popBtn">弹出新窗口</button>
<input type="text" name="" id="content">
<button id="btn">发送数据</button>
<script>
    const content = document.querySelector("#content")
    const btn = document.querySelector("#btn")
    const popBtn = document.querySelector("#popBtn")

   let opener=null  //用于保存window.open打开得窗口引用
    popBtn.onclick=function () {
        opener=window.open("index2.html","12131","height=400,width=400,top=20,resizeable=yes")

    }

    btn.onclick=function(){
       let data={value:content.value}
        //data代表得是要发送得数据,第二个参数是origin,使用*代表所有域
        opener.postMessage(data,"*")
    }
</script>
</body>
</html>

页面二:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面二</title>
</head>
<body>
<p>
    这是页面二
</p>
<script>
window.addEventListener('message',function (e) {
    console.log(e.data)
})
</script>
</body>
</html>

八、WebSocket

最大特点就是,服务器可以主动向客户端推送信息,而非客户端采用轮询得方法,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
页面一:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面一</title>
</head>
<body>
<input type="text" name="" id="msg">
<button id="send">发送信息</button>
<script>
    //建立websocket连接
    let ws=new WebSocket("ws://localhost:3000")
    let send=document.querySelector("#send")
    let msg=document.querySelector("#msg")
    send.onclick=function () {
        if(msg.value.trim()!==''){
            ws.send(msg.value.trim())
            let op1=document.createElement("p")
            op1.innerHTML=`我:${msg.value}`
            if(msg.value.trim()!==''){
                document.body.appendChild(op1)
            }
            msg.value=''
        }
    }

    let count=1 //用于计数
    ws.onopen=function () {
        ws.onmessage=function (event) {
            let op=document.createElement("p")
            op.innerHTML=`你:${event.data}`
            document.body.appendChild(op)
            count++
        }
    }

    //关闭窗口或者刷新得时候关闭webSocket连接
    window.onbeforeunload=function () {
        ws.close()
    }
</script>
</body>
</html>

页面二:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>页面二</title>
</head>
<body>
<input type="text" name="" id="msg">
<button id="send">发送信息</button>
<script>
    //建立websocket连接
    let ws=new WebSocket("ws://localhost:3000")
    let send=document.querySelector("#send")
    let msg=document.querySelector("#msg")
    send.onclick=function () {
        if(msg.value.trim()!==''){
            ws.send(msg.value.trim())
            let op1=document.createElement("p")
            op1.innerHTML=`我:${msg.value}`
            if(msg.value.trim()!==''){
                document.body.appendChild(op1)
            }
            msg.value=''
        }
    }


    let count=1 //用于计数
    ws.onopen=function () {
        ws.onmessage=function (event) {
            let op=document.createElement("p")
            op.innerHTML=`你:${event.data}`
            document.body.appendChild(op)
            count++
        }
    }


    //关闭窗口或者刷新得时候关闭webSocket连接
    window.onbeforeunload=function () {
        ws.close()
    }
</script>
</body>
</html>

websocket.js:

//获取WebSocketServer实例
let WebSocketServer = require("ws").Server

//创建websocket服务器
let wss = new WebSocketServer({
  port: 3000
});

//该数组用于保存所有得客户端连接实例
let clients =[]

//客户端连接上websocket服务器得时候就会触发connection事件,该客户端得实例就会传入此回调函数
wss.on('connection', function (client) {
  //保存客户端实例到clients
  clients.push(client);
  console.log("当前在线客户端数量:",clients.length)

  //给传入进来得客户端连接实例绑定一个message事件
  client.on('message', function (message) {
    console.log("收到得消息"+message)
    //图将接收到得信息推送给其他所有客户端
    for(let item of clients) {
      //排除自己,client:当前客户端
      if(item!==client){
        item.send(message.toString())
      }
    }
  })
  client.on('close', function () {
    let index=clients.indexOf(this)
    clients.splice(index,1)
    console.log("当前在线客户端数量:",clients.length)

  })
})
console.log("websocket服务器启动")

效果如图:
在这里插入图片描述

标签:function,浏览器,log,通信,跨页,let,console,document,页面
From: https://blog.csdn.net/weixin_61471530/article/details/144614050

相关文章

  • 最新版Chrome浏览器加ActiveX控件之多个VLC控件同时加载
     背景    VLCMediaPlayer是一款可播放大多数格式,而无需安装编解码器包的媒体播放器。可以播放MPEG-1、MPEG-2、MPEG-4、DivX、DVD/VCD、卫星数字电视频道、地面数字电视频道(digitalterrestrialtelevisionchannels)、在许多作业平台底下透过宽带IPv4、IPv6网......
  • 【ByPass】最新发现绕过浏览器隔离技术的攻击方法
    BaizeSec白泽安全实验室2024年12月10日15:26北京在网络安全领域,浏览器隔离技术一直被视为对抗网络钓鱼和基于浏览器的攻击的有效手段。然而,根据Mandiant的最新研究,攻击者已经找到了一种利用QR码绕过浏览器隔离的攻击方法,从而能够从远程服务器向受害设备发送恶意数据。浏览器......
  • 串行通信基础
    串行通信基础概念串行通信是单片机和外部设备之间最基础也最常用的一种数据传输方式。在了解串行通信之前,我们需要先理解数据传输的两种基本模式:并行和串行。并行通信就像多车道的高速公路,可以同时传输多位数据;而串行通信则像单行道,数据需要排队一位一位地传输。虽然从原理上......
  • 基于Java的动态交通信息服务系统设计与实现
    计算机毕业设计案例Java毕业设计案例ASP.NET毕业设计案例PHP毕业设计案例微信小程序毕业设计案例基于Java的村镇社区数据管理系统基于ASPNETMVC的网站式音乐播放基于php的微信小程序在线考试系统基于Java的“free美妆榜”微信小程序【12/19/02】基于Java后台的口罩查询......
  • COM(Component Object Model)接口是微软推出的一种用于软件组件间通信的技术,它允许不同
    COM(ComponentObjectModel)接口是微软推出的一种用于软件组件间通信的技术,它允许不同编程语言(如C++,C#,VB等)之间的对象进行交互。COM的核心概念包括接口、代理、类、类型库等,它广泛应用于Windows操作系统中。接下来我将详细介绍这些概念及它们在Windows运行时中的应用。1. COM......
  • 宝塔面板的自签名证书为什么不被公网浏览器信任?
    宝塔面板的自签名证书不被公网浏览器信任,主要是因为自签名证书没有经过权威的证书颁发机构(CA)的验证和签名。以下是几个主要原因:缺乏权威性:原因:自签名证书是由服务器自己生成的,没有经过任何第三方机构的验证。因此,浏览器无法确定这些证书的真实性和可信度。影响:浏览器会显示......
  • 通过浏览器JS跳转到微信小程序教程 代码支持移动端和pc端 复制即用!
    如何通过浏览器JS跳转到微信小程序?Tag:微信小程序跳转浏览器跳转小程序JS与小程序集成效果展示需求:最近在做一个H5页面,需要在用户点击某个按钮时跳转到对应的小程序页面,同时为了优化用户体验,我还需要在页面加载时显示跳转提示。这种需求在某些活动页或推广页中非......
  • linux中使用opencv的avi编码视频格式无法被浏览器访问
    avi编码介绍        AVI编码器,AVI英文全称为AudioVideoInterleaved,即音频视频交错格式。就是编码语音和影像同步组合在一起的文件格式。解决办法步骤:1. 卸载原来使用PyPI下载的opencv-python以及opencv-contrib-pythonpipinstallopencv-pythonopencv-con......
  • 浅谈一下本机、服务器、docker-compose 容器之间网络通信
    一、首先,先区分四个对象,它们分别有自己的网络1、云服务器上,应用服务容器网络(app,nginx,mysql,redis等)app.net2、云服务器上,模型服务容器网络(ai服务)模型网络ai.net3、云服务器上:宿主机网络(服务器本机)服务器本机网络host.net4、本机:本地网络local.netnginx和app在同一个......
  • 浏览器如何渲染inline元素中空格的?
    浏览器在渲染inline元素中的空格时,主要遵循以下规则和步骤:空格的识别与处理:浏览器会识别HTML代码中的空格字符,包括空格、换行符(如\n)和制表符(如\t)等。在解析和渲染过程中,浏览器通常会将多个连续的空格字符合并为一个空格进行处理,这是为了防止多余的空格影响页面的布局和显示......