基于Postmate实现的跨域通信
创始人
2024-01-21 07:05:56

1、Postmate 介绍

是一款基于 postMessage 来处理父子页面通信的库,轻量且好用。一个强大的、简单的、基于 promise 的 postMessage iFrame 通信库。

postmate 官方地址
https://github.com/dollarshaveclub/postmate

2、Postmate 特性

基于 promise 的 API,用于优雅和简单的通信。
安全的双向父 <-> 子握手,并带有消息验证。
子代暴露一个可检索的模型对象,父代可以访问。
子代发出事件,父代可以监听。
父代可以调用子代的函数。
零依赖性。如果需要的话,可以为 Promise API 提供自己的 polyfill 或抽象。
轻量级,大小约为 1.6kb(缩小和压缩后)。

3、Postmate 安装

//yarn
$ yarn add postmate
//npm
$ npm i postmate --save

4、Postmate 使用

这里提供一个 demo 内含 React 和 Vue 两个项目,其中 React 项目为父项目,Vue 项目为子项目,启动后,父项目会通过 iframe 方式自动加载子项目。

#父项目react
cd react
yarn
yarn start
#子项目vue-demo
cd vue-demo
yarn
yarn serve
  • 3、项目运行时截图和视频
    截图一:
    在这里插入图片描述

    截图二:
    在这里插入图片描述
    完整流程如下:
    在这里插入图片描述

  • 4、重要代码详解,父项目 react

import { useEffect, useRef, useState } from "react";
import yayJpg from "../assets/yay.jpg";import PostMate from "postmate";
import type { ParentAPI, PostmateOptions } from "postmate";import "./index.less";function HomePage() {const childRef = useRef(null);const [loading, setLoading] = useState(false);// 初始化const init = (params: PostmateOptions) => {console.log("++++++++++parent++++++++: 初始化parent页面postmate实例");const handshake = new PostMate({ ...params });// 回调handshake.then((child) => {console.log("++++++++++parent++++++++: 接收到child页面握手成功后,回传消息");// 存储child 到 childRef中childRef.current = child;child.on("some-event", (data) => {console.log(data);initChildParams();});// 更新UIupdateStyle(child);}).catch((error) => {console.log(error);});};useEffect(() => {init({container: document.getElementById("iframe-container"),url: "http://localhost:8080/",name: "my-iframe-name",classListArray: ["my-class"],});return () => {// 销毁iframechildRef.current.destroy();};}, []);// 更新UIconst updateStyle = (child: ParentAPI) => {// 采用轮训方式获取child页面高度setInterval(() => {child.get("height").then((height) => {child.frame.style.height = `${height + 80}px`;});}, 100);};// 设置child页面参数const initChildParams = () => {console.log("++++++++++parent++++++++: 调用child页面中defaultValues方法,设置表单默认参数");childRef.current.call("defaultValues",JSON.stringify({userErp: "yangyujiao5", //当前用户的erp,表单需要bamboolUrl: "bamboolUrl", //测试包链接sdkName: "sdkName", //SDK名称sdkVersion: "sdkVersion", //SDK版本}));};// 触发child页面的提交函数const onChildSubmitChange = (params: Record) => {return new Promise((resolve, reject) => {console.log("++++++++++parent++++++++: 调用child页面中onSubmit方法,触发child表单提交");// 触发child页面的onChildSubmit方法childRef.current.call("onSubmit", { ...params });// 在parent页面注册事件,用来获取child页面submit-callback方法childRef.current.on("submit-callback", (data: any) => {console.log("++++++++++parent++++++++: 接收到child页面表单提交成功后通知");if (data?.code === 200) {resolve(data);} else {reject();}});});};// parent提交函数const onSubmit = async () => {console.log("++++++++++parent++++++++: 触发parent页面表单提交方法");try {setLoading(true);const { code, sdkID } = await onChildSubmitChange({ id: 21 });console.log(code, sdkID);// return {code, sdkID}// child表单提交成工后,触发parent页面提交if (code !== 200) return;console.log("++++++++++parent++++++++: parent页面表单提交成功后,调用child页面onFinishCallback方法");//parent页面提交任务结束后,通知child页面childRef.current.call("onFinishCallback", { parent_id: 2 });// 在parent页面注册finish-callback,等到该方法执行完成后,则完成一次iframe交互childRef.current.on("finish-callback", (data: any) => {console.log("++++++++++parent++++++++: 接收到child页面完成onFinishCallback通知",data);if (data?.code === 200) {setLoading(false);}});} catch (error) {console.log(error);}};return (

Yay! Welcome to umi!

{ overflow: "hidden" }}>
); }export default HomePage;

子项目 vue


如果涉及到内嵌多个 iframe 的情况下,可参考以下 postmates-js 实现

https://gitee.com/videring/postmates-js

相关内容

热门资讯

长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
不用扬鞭自奋蹄 乘势而上千帆竞... 思明区正全力向“两个进位”目标发起冲刺,努力为建设高素质高颜值现代化国际化的厦门作出“思明贡献”。(...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
好听的民谣歌曲 2021最火的... #我的年度歌单#在2021年里听过很多民谣,但是最能触及心中温柔的还是下面的几首。不听民谣的理由有很...