【场景方案】我所积累的一些跨页面的数据传递方式,持续更新,欢迎补充~

news/2024/7/19 15:28:50 标签: 前端, js, javascript

文章目录

  • Iframe内嵌相互传递
  • BroadcastChannel同标签页数据传递
  • localStorage中间人传递
  • 未完待续...

Iframe内嵌相互传递

使用window.postMessage()的这个html5特性去跨域传递数据,不受跨域限制。

父层:

sendMes(){ // 向iframe发送
	let iframdom = this.$refs.iframdom // 拿到iframe的dom
	let _window = iframdom.contentWindow // 拿到iframe的window对象
	let _document = iframdom.contentDocument // 拿到iframe的document对象
	_window.postMessage({type: 'sendMes', text: '内容'}, '*') 
	// 注意点:1 第一个参数传内容用对象装,因为webpack会默认主动触发一次,
	// 即使sendMes没执行,这样被第一次触发的时候我们能通过对象的内容去区分。
	// 2 第二个参数写传入的地址是什么,如果不限制地址写*即可
}

window.addEventListener("message", (e) => { // 接收子层
	// e.data及postMessage的第一个参数,e.origin及postMessage的第二个参数
})

子层:

window.addEventListener("message", (e) => { // 接收父层
	// e.data及postMessage的第一个参数,e.origin及postMessage的第二个参数
})

sendOut(){ // 向父层发送
	window.top.postMessage({type: 'sendMes', text: '内容'}, '*') 
}

个人对这个api的看法:

  • 能够支持跨域,这样不同项目的网站都能相互通信了。
  • 当传输的内容多了,整个工程到处都是postMessage,到处监听,会非常的混乱(建议监听统一放到类似App.vue的组文件中)。
  • 父层与子层需要定好规则,例如你的项目是子层,就要去问负责开发父层网站的开发人员,怎么按照他们的规范去传递数据和获取回数据

这里推荐篇基础使用文章:【记录postMessage的详细使用】
再推荐篇补充的:【终于搞懂了 Iframe (跨窗口通信)】


BroadcastChannel同标签页数据传递

这个api适合同一个浏览器中,访问多个标签页,标签页之间的通信:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    </style>
</head>

<body>
    <button id="btn">点击</button>
    <script>javascript">
        let btnDom = btn
        const channel = new BroadcastChannel('card')

        btnDom.onclick = function () {
            channel.postMessage({
                a: 1
            })
        }

        channel.onmessage = (e) => {
            console.log('监听到信息', e.data);
        }

    </script>
</body>

</html>

当a标签页点击了按钮,b标签页就能够接收到数据。兼容性也很好。

当然在框架中使用有些注意事项:

用添加监听器的方式去监听channel的信息传递,这样好销毁内存

javascript">channel.addEventListener('message', handler)
channel.removeEventListener('message', handler) // 销毁

还有一个要注意的,如果postMessage时传入的是框架里的响应式变量是会报错的,传入的时候用…处理下。

综上,最好单独写个js文件去调用BroadcastChannel:

javascript">const channel = new BroadcastChannel('demo')

export function sendMsg(type, content) {
	channel.postMessage({
        type,
        content,
    })
}

export function listenMsg(callback) {
	const handler = (e) => {
		callback && callback(e.data)
	}
	channel.addEventListener('message', handler)
	return ()=>{
		channel.removeEventListener('message', handler) // 让组件在使用的时候能够得到销毁函数,在生命周期钩子中销毁
	}
}

localStorage中间人传递

localStorage是可以跨页签的,只要是同域的都共用一个localStorage缓存,利用这个特性可以:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    </style>
</head>

<body>
    <button id="setData">存储</button>
    <button id="getData">获取</button>
    <script>javascript">
        let setDataDom = setData
        let getDataDom = getData

        setDataDom.onclick = function () {
            localStorage.setItem('a', 1)
        }

        getDataDom.onclick = function () {
            console.log(localStorage.getItem('a'));
        }

    </script>
</body>

</html>

iframe嵌套相同域名的页面应该也是可以正常使用的,不过

  • 多占用localStorage资源
  • 无法做到主动接收

这里提个醒sessionStorage每个页签都是独立的


未完待续…


http://www.niftyadmin.cn/n/4993657.html

相关文章

【Docker】03-安装redis

安装Redis 1、拉取最新的redis镜像 docker pull redis 2、启动redis docker run --name redis -p 6379:6379 -d redis 3、查看启动日志 docker logs -t -f 容器id|名称 4、进入容器内部查看 docker exec -it 容器id|名称 bash 5、使用自定义配置启动 默认情况下&#xff0…

并发测试工具 apache-jmeter使用发送post请求JSON数据

目录 1 下载安装 2 汉化 3 创建高并发测试 配置线程组 创建web请求 创建监听器 结果树 汇总报告 为web请求添加token 添加Content-Type用于发送json 4 启动测试 5 查看结果 1 下载安装 官网Apache JMeter - Download Apache JMeter 解压运行 2 2 汉化 打开软件…

layui实现数据列表的复选框回显

layui版本2.8以上 实现效果如图&#xff1a; <input type"hidden" name"id" id"id" value"{:g_val( id,0)}"> <div id"tableDiv"><table class"layui-hide" id"table_list" lay-filter…

电缆工厂 3D 可视化管控系统 | 智慧工厂

近年来&#xff0c;我国各类器材制造业已经开始向数字化生产转型&#xff0c;使得生产流程变得更加精准高效。通过应用智能设备、物联网和大数据分析等技术&#xff0c;企业可以更好地监控生产线上的运行和质量情况&#xff0c;及时发现和解决问题&#xff0c;从而提高生产效率…

Python面试:什么是GIL

1. GIL (Global Interpreter lock)可以避免多个线程同时执行字节码。 import threadinglock threading.Lock()n [0]def foo():with lock:n[0] n[0] 1n[0] n[0] 1threads [] for i in range(5000):t threading.Thread(targetfoo)threads.append(t)for t in threads:t.s…

【CSS】组合选择器

组合选择器&#xff08;Combinator Selectors&#xff09;是一种CSS选择器&#xff0c;用于选择满足多个选择器条件的特定元素。组合选择器由两个或多个简单选择器组合而成&#xff0c;它们描述了元素之间的关系。这些关系可以是父子关系、兄弟关系等&#xff0c;从而允许您更精…

2.(Python数模)线性规划问题

Python解决线性规划问题 参考了以下博文 https://blog.csdn.net/m0_46692607/article/details/126784109?spm1001.2014.3001.5506 目标是解决以下的线性规划&#xff0c;程序计算出目标函数的最大值&#xff0c;并在最大值下取得的x1x2x3对应值。 源代码如下&#xff1a; …

Angular安全专辑之三 —— 授权绕过,利用漏洞控制管理员账户

这篇文章是针对实际项目中所出现的问题所做的一个总结。简单来说&#xff0c;就是授权绕过问题&#xff0c;管理员帐户被错误的接管。 详细情况是这样的&#xff0c;我们的项目中通常都会有用户身份验证功能&#xff0c;不同的用户拥有不同的权限。相对来说管理员账户所对应的…