【VUE】localStorage、indexedDB跨域数据操作实战笔记
由于业务需求,最近研究localStorage、indexedDB等如何跨域进行CRUD管理,经过一番研究,封装了如下代码并做个笔记
环境
- vue:
^3.3.4
实战
发送端(即触发站点)
在App.vue
中引入CrossDomainStorage
组件(后面有实现过程)
<script setup>
import { ref } from 'vue'
import CrossDomainStorage from "@/components/CrossDomainStorage/index.vue";
const crossDomainStorageRef = ref(null)function sendTest() {if (crossDomainStorageRef.value){crossDomainStorageRef.value.sendMessage("getItem", {key:'APP_THEME_SCREEN'})}
}
</script><template><div><button @click="sendTest">测试</button><CrossDomainStorage :src="'http://xxxx.xxx/'" ref="crossDomainStorageRef"/></div>
</template>
接收端(即目标站点)
为了方便直接在App.vue
中实践
<script setup>
import ParentMsgListener from '@/utils/parentMsgListener'const parentMsgListener = new ParentMsgListener()
parentMsgListener.addPermissionModule({ // 设置权限key对应处理方法localStorage: {setItem: localStorage.setItem,getItem: localStorage.getItem,},asyncTest: {text: async ()=> await 'asyncValue',text2: () => 'testValue',}
});
parentMsgListener.addPermission([ // 设置可操作的对象列表'localStorage'
])
parentMsgListener.start();
</script>
实现代码
CrossDomainStorage
组件
<script setup lang="ts">
import {ref, reactive, onMounted} from 'vue';defineOptions({name: 'CrossDomainStorage'
});const iframeRef = ref();
const emit = defineEmits(['onLoad','response'])
const props = defineProps({src: {type: String, default:()=>"", required:true}
});
const status = ref(false)
const iframeStyles = reactive({position: 'fixed',top:0,left:0,width: 0,height: 0,zIndex:-1
});window.addEventListener('message', function (e) {if (e.data && e.data.request){console.log('[发送端]从iframe获取数据', e.data)emit('response', e.data||null)}
});function sendMessage(method: string, param: object, key: string) {if (status.value===false)return;key = key?key:'localStorage'if (iframeRef?.value){const iframeNode = iframeRef.value.contentWindow;let request = {key, method, param}console.log('[发送端]向iframe发送request:', request)setTimeout(function () {iframeNode.postMessage(request, '*')}, 500)}
}defineExpose({sendMessage: (method: string, param: object, key: string)=>sendMessage(method, param, key)
})onMounted(()=>{if (!!iframeRef.value && !!iframeRef.value.contentWindow){iframeRef.value.onload = function () {status.value = true;emit('onLoad', true)}}
})
</script><template><iframe ref="iframeRef" :src="props.src":style="iframeStyles"frameborder="0"scrolling="no"/>
</template>
parentMsgListener.ts
封装消息管理类
// src/utils/parentMsgListener.ts
const messageLog = function (log, ...arg){arg.unshift(`[接收端]`, log)console.log.apply(console, arg)
}interface permissionOptions {key: string[],module: object
}/*** 监听响应拦截** @param {object} e 接收数据* @param {array} permission 权限列表* @param {function} response 接收回调** @return {void}*/
const listenerResponse = async function (e, permission: permissionOptions, response) {if (e.data && !!e.data.key && permission.key.includes(e.data.key)){let result = undefined;let lib = permission.module[e.data.key] || undefined;let method = e.data?.method || '';let param = e.data?.param||{};if (!!lib){let _param = [];for (let key in param){_param.push(`'${param[key]}'`)}try { // 调用非js内置方法且兼容异步调用处理方法result = await ((lib[method]).apply(lib[method], Object.values(param)));}catch (error) { // 调用js内置方法result = eval(`${e.data.key}.${method}(${_param.join(',')})`);}}messageLog('response:', result)response({request: e.data,response: result}, '*')}
}class ParentMsgListener {/*** 消息调用权限对应处理* @var {object}*/private permissionMap = {};/*** 消息允许调用权限* @var {string[]}*/private permission = []constructor(permission) {if (permission && permission.length>0){this.addPermission(permission)}}/*** 添加授权权限key对应处理模块** @param {string|object} name 权限key* @param {function} fn 权限key处理方法** @return this*/addPermissionModule(name:string|object, fn){if (!fn && typeof name === 'object'){ // 批量导入for (let moduleKey in name){this.addPermissionModule.call(this, moduleKey, name[moduleKey]);}}else if(typeof name === 'string' && !!fn) { // 逐个导入this.permissionMap[name] = fn;}return this;}/*** 添加授权权限** @param {string|string[]} permissionKey 权限key** @return this*/addPermission(permissionKey: string|string[]){if (permissionKey instanceof Array){let that = this;permissionKey.forEach((key)=>{that.permission.push(key)})}else{this.permission.push(permissionKey)}return this;}/*** 发送消息** @param {object} message 发送内容* @param {string} targetOrigin 默认:*** @return {void}*/sendMessage(message:any, targetOrigin:string = '*'){messageLog('发送消息', message)window.parent.postMessage(message, targetOrigin)}/*** 启动监听*/start(){window.addEventListener('message',(e)=>listenerResponse(e, {key: this.permission,module: this.permissionMap}, this.sendMessage))}
}export default ParentMsgListener
相关文章:
【VUE】localStorage、indexedDB跨域数据操作实战笔记
由于业务需求,最近研究localStorage、indexedDB等如何跨域进行CRUD管理,经过一番研究,封装了如下代码并做个笔记 环境 vue: ^3.3.4 实战 发送端(即触发站点) 在App.vue中引入CrossDomainStorage组件(后面有实现过程) <script setup&g…...

四、web应用程序技术——HTTP
文章目录 1 HTTP请求2 HTTP响应3 HTTP方法4 URL5 HTTP消息头5.1 常用消息头5.2 请求消息头5.3 响应消息头 6 cookie7 状态码8 HTTP代理9 HTTP身份验证 HTTP(HyperText Transfer Protocol,超文本传输协议)是访问万维网使用的核心通信协议&…...

B2B2C小程序商城系统--跨境电商后台数据采集功能开发
搭建一个B2B2C小程序商城系统涉及到多个步骤和功能开发,其中包括跨境电商后台数据采集功能的开发。具体搭建步骤如下: 一、系统搭建 1. 确定需求和功能:根据B2B2C商城的需求,确定系统的功能和模块,包括商品管理、订单…...

Python-OpenCV中的图像处理-形态学转换
Python-OpenCV中的图像处理-形态学转换 形态学转换腐蚀膨胀开运算闭运算形态学梯度礼帽黑帽形态学操作之间的关系 形态学代码例程 形态学转换 形态学操作:腐蚀,膨胀,开运算,闭运算,形态学梯度,礼帽,黑帽等…...

理解 Python 的 for 循环
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 在本篇博客中,我们将讨论 Python 中 for 循环的原理。 我们将从一组基本例子和它的语法开始,还将讨论与 for 循环关联的 else 代码块的用处。 然后我们将介绍迭代对象、迭代器和迭代器协议&…...

携程验证码
今日话题:凑字数水文章。大表哥们感兴趣可以看看。 携程验证类型总共有3种。无感,滑块,点选。 process_type:None为无感 验证接口:https://ic.ctrip.com/captcha/v4/risk_inspect process_type:JIGSAW为…...

资深媒体人宋繁银加入《数据猿》任总编辑,全面负责公司整体内容工作
大数据产业创新服务媒体 ——聚焦数据 改变商业 2023年7月北京,《数据猿》宣布正式任命宋繁银为总编辑,全面负责公司整体内容工作。此次重要的人事任命标志着《数据猿》的发展迈上了一个新的台阶,对于《数据猿》团队而言,不仅是一…...
【Unity实战100例】人物状态栏UI数据刷新—MVC观察者模式
目录 一.创建Model层数据模型 二.创建View层关联UI组件 三.创建Controller层使得V和M数据关联 源码:htt...

8路AD采集FMC子卡【产品资料】
FMC148是一款基于VITA57.4标准的JESD204B接口FMC子卡模块,该模块可以实现8路14-bit、500MSPS/1GSPS/1.25GSPS ADC采集功能。该板卡ADC器件采用ADI公司的AD9680芯片,全功率-3dB模拟输入带宽可达2GHz。该ADC与FPGA的主机接口通过16通道的高速串行GTX收发器进行互联。 …...
文章三:团队协作实践 - 协作高手:Git团队开发最佳实践
开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun 概述 在现代软件开发中,团队协作是必不可少的环节。而Git作为目前最受欢迎的分布式版本控制系统&a…...
Pyinstaller 打包 django 项目如何将命令行参数加入?
起因 Pyinstaller 打包 django 项目,打包成 manage.exe 后用命令行 cmd manage.exe 0.0.0.0:8001 --noreload 感觉很不方便。 希望能够直接把命令行参数也打包进去。 我是这样做的: 步骤 1.新建 main.py 文件 import osos.system(manage.exe runser…...
hive锁的管理器的介绍
各个管理器的使用: org.apache.hadoop.hive.gl.lockmgr.DbTxnManager 在 Hive 中被用于实现事务和锁的管理机制。它的使用场景通常涉及以下情况: ACID事务支持:当需要在 Hive 中进行复杂的数据操作,并确保这些操作以原子性、一致…...

以太网TCP协议(十二)
目录 一、概述 二、功能 2.1 连接管理 2.2 响应与序列号 2.3 超时重发 2.4 传输单位:段 2.5 窗口控制 2.6 流控制 2.7 拥塞控制 2.8 效率提高 三、报文格式 一、概述 TCP作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据&…...
ARM 架构下的汇编指令(持续更新中)
ARM 架构下的汇编指令 1. 预取指令1.1. pldw1.2. pld1.3. 使用场景 2. ldrex3. teq4. 条件分支指令4.1. beq4.2. bne 1. 预取指令 1.1. pldw pldw 是 “Prefetch Load Data for Write” 的缩写,pldw 指令用于预取写操作,它告诉处理器需要预先加载指定地…...

11款UML/SysML建模工具更新(2023.7)Papyrus、UModel……
DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 最近一段时间更新的工具有: 工具最新版本:drawio-desktop 21.6.5 更新时间:2023年7月22日 工具简介 开源绘图工具,用Electron编写,…...

FPGA外部触发信号毛刺产生及滤波
1、背景 最近在某个项目中,遇到输入给FPGA管脚的外部触发信号因为有毛刺产生,导致FPGA接收到的外部触发信号数量多于实际值。比如:用某个信号源产生1000个外部触发信号(上升沿触发方式)给到FPGA输入IO,实际…...

day38 滑动窗口
1. 滑动窗口 应用场景: 满足xxx条件(计算结果、出现次数、同时包含) 关键词:最长最短子串无重复等等 1)最长 左右指针在起始点,R 向右依次滑动循环; 如果: 窗内元素满足条件&#x…...
翻出了我当时学习的笔记来了html
php:高级语言 web应用程序 万维网 浏览器中查看 apache:服务器 mysql:数据库 html 标签 css:层叠样式表 javascript:客户端脚本 js jquery mysql数据库基础 php语法基础 面向对象(物件) smar…...

vuejs 设计与实现 - 快速diff算法
Vue.js 2 所采用的双端 Diff 算法。既然快速 Diff 算法如此高效,我们有必要了解它的思路。接下来,我们就着重讨论快速 Diff 算法的实现原理。 相同的前置元素和后置元素 快速 Diff 算法借鉴了纯文本 Diff 算法中预处理的步骤。 案例: 旧的…...

webpack基础知识七:说说webpack proxy工作原理?为什么能解决跨域?
一、是什么 webpack proxy,即webpack提供的代理服务 基本行为就是接收客户端发送的请求后转发给其他服务器 其目的是为了便于开发者在开发模式下解决跨域问题(浏览器安全策略限制) 想要实现代理首先需要一个中间服务器,webpac…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...