A项目使用iframe
内嵌了一个B项目的几个页面,A和B 都是vue2项目,A和B是父子内嵌关系,A和B 会有端口不同的情况,所有沟通起来会有跨域问题(前-后端,A前端页面-B前端页面),采用window.parent.postMessage方法主要解决的是A前端-B前端页面的问题,B页面token丢失时,要求页面跳转到A页面的登录页面,(如果在B页面直接使用window.location(‘A页面的登录页’)
方法会不断内嵌很多个·‘A页面的登录页’
,所以只能跳出这个内嵌页面,直接调取A页面的跳转方法才行,这就涉及到了,跨域时子页面调取父页面方法的问题
如何定义父子页面?
刚开始想的是不是只有是,A项目里使用了iframe
的这个组件才是父页面,最后一想,vue就是个单页面组件,App.vue就是B最大的父亲!所以直接在App.vue里写方法了;现在的文件关系是
介绍上面文件关系的目的是
想说的是该方法不要拘泥于xx.vue文件只能和xxx.vue文件通信;.vue文件和和.js文件通信,因为方法最终都是转化成js文件
简介
/**
* otherWindow:其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行 window.open 返回的窗口对象、或者是命名过或数值索引的 window.frames、或者父级window.parent
* message:将要发送到其他 window的数据
* targetOrigin:指定哪些窗口能接收到消息事件,其值可以是 *(表示无限制)或者一个 URI。
* transfer:可选,是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
*/
otherWindow.postMessage(message, targetOrigin, [transfer]);
代码(vue2)
// 父页面: A项目的App.js
<script>
export default {
mounted(){
// 在挂载函数里写监听函数
window.addEventListener('message', this.receiveMessage, false)
},
methods:{
// 监听时调用的函数,也可以直接写在 window.addEventListener里
receiveMessage(event){
if (event.data == 'CallParentMethod') {
// 执行父页面的方法
this.$router.replace('/')
}
}
}
}
</script>
// 子页面: B组件的axios封装的js文件(request.js)
// 响应拦截里报错后的某一个判断里
/**
* 缺失token直接登出,
*/
if(res.result=="缺少Token" ||res.result =='无效Token'){
// let targetOrigin = 'http://xxxx'; // 父页面的域名、url
// 我这里使用的*
window.parent.postMessage('CallParentMethod', '*');
}
之前写js时一直用,现在好久没用了忘记了
/**
* event:必须。字符串,指定事件名。注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。提示: 所有 HTML DOM 事件,可以查看我们完整的 HTML DOM Event 对象参考手册。
* function:必须。指定要事件触发时执行的函数。当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件) 对象。
* useCapture:可选。布尔值,指定事件是否在捕获或冒泡阶段执行。true - 事件句柄在捕获阶段执行,false- false- 默认。事件句柄在冒泡阶段执行
*/
element.addEventListener(event, function, useCapture)
//message:该事件通过或者从对象(WebSocket, Web Worker, Event Source 或者子 frame 或父窗口)接收到消息时触发