不良网站代码怎么查,买了域名和空间怎么做网站,logo制作用什么软件,军事新闻2022目录 1#xff0c;需求2#xff0c;难点3#xff0c;思路浏览器不同源的页面之间如何跨域通信#xff1f; 4#xff0c;实现第1版第2版最终版其他的问题1#xff0c;页面路径需完全一致。2#xff0c;事件注册问题 1#xff0c;需求
现在有2个项目#xff0c;页面路径… 目录 1需求2难点3思路浏览器不同源的页面之间如何跨域通信 4实现第1版第2版最终版其他的问题1页面路径需完全一致。2事件注册问题 1需求
现在有2个项目页面路径不同源。
ToC 的收银台项目 类似在PC端京东淘宝支付最后一步的收银台页面可以选择不同支付工具付款。 ToB 的后台管理项目 可以对收银台项目整体做一些配置样式支付工具相关的等等配置项很多。 需求
想要在后台管理项目中增删配置项后能够实时预览收银台项目最终的展示效果展示效果符合预期则提交修改配置项的审批电子流审批通过上线
2难点
因为2个项目的页面路径不同源传递数据是个问题。
3思路
首先后台管理项目需要增加【预览】按钮收银台项目需要增加【预览】页面。 需要后端参与。收银台项目的相关配置项本来就是通过接口获取的。所以再增加一个预览数据的接口在预览页面调用获取数据。 不需要后端参与。前端直接在2个页面之间通信。
第1种思路没有什么好说的重点来说下第2种。
浏览器不同源的页面之间如何跨域通信 通过 url 传参。最简单直接不过传递的数据大小有限。 postMessage传递的数据大小我实测可以超200MB不知道极限因为没再往上测试
简单来说我们可以获取从当前页面A通过window.open打开的页面B的引用 targetWindowB然后在A页面通过 targetWindowB.postMessage() 向B页面分发消息。
再介绍下 window.open
简单说明window.open 有3个参数我们只关注前2个
strUrl新页面的地址strWindowName新页面的名称如果指定了该参数则再次调用 window.open(strUrl, strWindowName) 时不会再打开第2个新页面而是跳转到打开的第1个页面并重新加载。效果下面会有展示
另外需要注意调用window.open()方法以后远程 URL 不会被立即载入载入过程是异步的。 会有什么问题看下实现过程就知道了。
4实现
通过 vite 创建2个项目模拟A 会向 B 发送数据。启动后的页面地址分别是
A页面后台管理项目 managehttp://localhost:5173B页面收银台项目 cashierhttp://localhost:5174
第1版
A页面后台管理项目 manage
script setup
const cashierUrl http://localhost:5174;
const data { name: 下雪天的夏风 };
let cashierWindow;function init() {cashierWindow window.open(cashierUrl, cashierWindow);if (cashierWindow) {cashierWindow.postMessage(data, cashierUrl);}
}
/scripttemplateh1manage/h1button clickinit发送预览数据/button
/templateB页面收银台项目 cashier
script setup
window.addEventListener(message,function (event) {if (event.origin ! http://localhost:5173) return;if (event.data) {console.log(event.data);}},false
);
/scripttemplateh1cashier/h1
/template效果 可以看到收银台项目并没有接收到消息
原因就是调用window.open()方法以后远程 URL 不会被立即载入载入过程是异步的。
换句话说因为B页面还没有加载完成message 事件还没有被绑定时A页面已经把消息发送了。
第2版
延迟发送消息。
function init() {cashierWindow window.open(cashierUrl, cashierWindow);setTimeout(() {if (cashierWindow) {const data { name: 下雪天的夏风 };cashierWindow.postMessage(data, cashierUrl);}}, 1000);
}效果 B页面成功收到消息
问题来了因为这个测试用例比较简单所以 1s B页面就会加载完成。 可面对复杂的页面网络问题A页面如何知道B页面已经加载完成了message 事件绑定了
答案是此时B页面可以通过 window.opener 获取 A页面的引用使用 postMessage 向A页面发送数据
实现思路
B页面加载完成后通过window.opener.postMessage() 向A页面发送一个约定字段。A页面接收到约定字段后再向B页面发送目标数据。
最终版
A页面后台管理项目 manage
script setup
import { ref } from vue;
const cashierUrl http://localhost:5174;
const cashierLoaded ref(false);
let cashierWindow;function init() {cashierWindow window.open(cashierUrl, cashierWindow);if (cashierLoaded.value) {requestData();} else {window.addEventListener(message, receiveMessage, false);}
}function receiveMessage(event) {if (event.origin ! cashierUrl) return;cashierLoaded.value event.data __done__;requestData();
}const data { name: 下雪天的夏风 };
function requestData() {cashierWindow.postMessage(data, cashierUrl);
}
/scripttemplateh1manage/h1button clickinit发送预览数据/button
/templateB页面收银台项目 cashier
script setup
const manageUrl http://localhost:5173;if (window.opener) {window.opener.postMessage(__done__, manageUrl);
}window.addEventListener(message,function (event) {if (event.origin ! manageUrl) return;if (event.data) {console.log(event.data);}},false
);
/scripttemplateh1cashier/h1
/template效果 其他的问题
1页面路径需完全一致。
2个不同源页面通信时要注意设置的 url 要完全一致才能接收到消息。例如 http://localhost:5174 和 http://localhost:5174/ 是不一样的
2事件注册问题
看下面的代码
function init() {cashierWindow window.open(cashierUrl, cashierWindow);if (cashierLoaded.value) {requestData();} else {window.addEventListener(message, receiveMessage, false);}
}function receiveMessage(event) {if (event.origin ! cashierUrl) return;cashierLoaded.value event.data __done__;requestData();
}init 方法中每次都要执行window.open 吗不能把 cashierWindow 保存起来调用requestData 吗 也可以这样做。但这个例子中是为了每次执行后默认跳转到 B页面并刷新。 init 方法中每次都要注册message 事件吗万一打开的B页面加载较慢又返回到A页面再次点击发送数据岂不是又会再次注册事件吗 确实会再次注册事件不过没关系因为注册相同的事件监听器多余的监听器会被移除只保留一个。参考 只保留一个的前提是事件回调函数不能是匿名函数否则还是会注册多个所以把 receiveMessage 提取出来了。 我们来验证下最终版代码的效果 而如果监听 message 事件这样写
window.addEventListener(message,// function receiveMessage(event) { // 效果一样function(event) {if (event.origin ! cashierUrl) return;cashierLoaded.value event.data __done__;requestData();},false);再来看下效果 以上。如果对你有帮助可以点赞支持下