【VUE】localStorage、indexedDB跨域数据操作实战笔记

这篇具有很好参考价值的文章主要介绍了【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中实践文章来源地址https://www.toymoban.com/news/detail-632852.html

<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跨域数据操作实战笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SpringBoot+Vue】全网最简单但实用的前后端分离项目实战笔记 - 数据库设计

    配套视频地址:https://www.bilibili.com/video/BV1dG4y1T7yp/ 如果您需要原版笔记,请up喝口水,可以上我的淘宝小店 青菜开发资料 购买,或点击下方链接直接购买: 源码+PDF版本笔记 源码+原始MD版本笔记 感谢支持!

    2024年02月16日
    浏览(35)
  • Vue中如何进行本地存储(LocalStorage)

    在Vue.js应用程序中,本地存储(LocalStorage)是一个强大的工具,用于在浏览器中保存和检索数据。它允许您在不使用服务器或后端数据库的情况下,在用户的浏览器中存储数据,以实现数据的持久性。本地存储对于保存用户首选项、用户身份验证令牌、购物车数据等场景都非

    2024年02月07日
    浏览(46)
  • Vue3优雅地监听localStorage变化

    目录 💡前言  💡 为什么要这样做? 💎 思路 💎 实现 🚗 实现中介者模式 🚗 重写localStorage 🚗 实现useStorage hook 💎 测试 🚗 使用localStorage 🚗 监听localStorage变化 🚗 结果         最近在研究框架,也仔细用了Vue3一些功能,今天分享一次我的实践:         原生的

    2024年02月08日
    浏览(50)
  • token + localstorage 验证登录(vue)详细教程

    token : 本质是验证身份的令牌,一般由用户通过账户密码登录后,服务端把这些凭证通过加密等一些列操作后得到的字符串。 token 登录流程: 客户端用账户密码请求登录; 服务端接收请求,验证账户密码; 验证成功后,服务端发送token给客户端; 客户端接收到token后保存,

    2023年04月21日
    浏览(31)
  • 【Vue】浏览器缓存sessionStorage、localStorage、Cookie

    目录 一、sessionStorage 1、简介 2、方法 3、代码示例 a、存取单个数据 b、存取对象 c、清除数据 二、localStorage 1、简介 2、方法 3、代码示例 三、cookie 1、简介 2、方法 3、代码示例 四、三者区别 1、sessionStorage与localStorage区别 2、sessionStorage、localStorage、cookie区别 五、往期相关优

    2024年02月07日
    浏览(36)
  • Vue中如何进行状态持久化(LocalStorage、SessionStorage)

    在Vue应用中,通常需要将一些状态进行持久化,以便在用户关闭浏览器或刷新页面后,仍能保留之前的状态。常见的持久化方式包括 LocalStorage 和 SessionStorage 。本文将介绍如何使用这两种方式来实现状态的持久化。 LocalStorage 是HTML5中引入的一种持久化方式,它可以将数据存储

    2024年02月09日
    浏览(50)
  • 在Vue 3中使用useStorage轻松实现localStorage功能

    VueUse 介绍 VueUse文档:Get Started | VueUse VueUse是基于Vue3的Composition API的实用函数的集合, useStorage 是其中的一个函数。我们可以使用 useStorage 来实现我们的 localStorage 功能。 安装 使用CDN useStorage() 的用法 useStorage () 将要用于引用的键名作为第一个参数传递,将要保存的值作为第

    2024年02月05日
    浏览(38)
  • node+vue开发环境下接口数据传递中的跨域问题

    大部分浏览器自带的保护措施,限制用户在一个域名下请求另一个域名的数据 跨域对于前后端开发者来说,就像一块狗皮膏药,无论是面试还是开发中,都会经常遇到。 之所以出现跨域问题,是因为浏览器的同源策略,为了隔离潜在的恶意文件,为了防御来自歪门邪道的攻

    2024年01月24日
    浏览(52)
  • VUE项目使用axios发送post跨域请求,返回数据失败问题

    Access to XMLHttpRequest at \\\'http://xxxx\\\' from origin \\\'http://localhost:8080\\\' has been blocked by CORS policy: Response to preflight request doesn\\\'t pass access control check: No \\\'Access-Control-Allow-Origin\\\' header is present on the requested resource. 第一步 ,在后端接受方,对返回的数据添加 响应头 ,使用下面这句代码: 第二步

    2024年02月11日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包