相关文章推荐
英俊的大脸猫  ·  Window postMessage() ...·  1 年前    · 
憨厚的小马驹  ·  [sql server] ...·  1 年前    · 

最近有一个需求是从当前项目带着token和uuid点击按钮跳转到另一个不同域名的项目去,在纠结了多个跨域通信的方法后,最后选择较简单的postMessage来进行通信

PostMessage

介绍:通常只有符合同源策略的两个页面才能相互通信,window.postMessage()方法提供了一种受控机制来规避此限制,就能安全的实现跨源通信

otherWindow.postMessage(message, targetOrigin, [transfer])
otherWindow:其它窗口的引用,比如iframe的contentWindow属性,执行window.open返回的窗口对象,window.open打开过页面获取到的window.opener,或者是命名过或数值索引的window.frames
message:将要发送到其他 window 的数据,它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化
targetOrigin:指定哪些窗口能接收到消息事件,其值可以是 *(表示无限制)或者一个 URI,在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送
transfer(可选):是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权(一般不会使用)

message中的属性有:

data:从其他 window 中传递过来的对象
origin:调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成,这个 origin 不能保证是该窗口的当前或未来 origin,因为 postMessage 被调用后可能被导航到不同的位置
source:对发送消息的窗口对象的引用; 您可以使用此来在具有不同 origin 的两个窗口之间建立双向通信
// 先通过window.open打开窗口,因为根据网速和页面大小,window.open打开网页的时间不确定,最开始使用setTimeout在间隔
// 2000ms后发送data,发现网速一卡就接受失败,所以这里在接受方页面load加载完成后,再发送加载完成的信息到发送方,发送方
// 接受到信息后再传输数据过去
const domain = window.open('http://localhost:8082/#/progress-bar')
// 通过message监听事件接受到信息后再postMessage
window.addEventListener(
        'message',
        (e) => {
            domain .postMessage({token: sessionStorage.getItem('token'),uuid,},
                'http://localhost:8082'
            )}, false)
window.addEventListener('load', () => {
	// window.opener是对父页面,也就是跳转前页面的引用参数,在load完成后传输数据过去
	window.opener.postMessage('子页面加载完毕', 'http://192.168.0.149:5173')
window.addEventListener('message', (e) => {
	// 当e.origin是发送方的端口号时再接受数据
	if (e.origin === 'http://192.168.0.149:5173') {
		console.log(e.data, '接受到的数据')
}, false)

每次用完此监听事件可以在接收或者发送完数据后对此监听事件进行移除

window.removeEventListener('message', function)

如果有帮助到各位大佬们,记得双击收藏关注点赞,关注必回!!!

第一种方式 最近在做web项目,碰到需要跨页面传递参数的功能,就是那种需要把当前页面的内容带到新开的子窗体,以前的做法是传一个id过去,然后在新窗口去读数据库的内容。虽然不怎么麻烦,但是如果内容么有在数据库里保存,仅仅是处以拟稿状态时,就不能实现了,用户还常常认为是个bug。考虑采用get的方式传递,把需要的内容都序列化然后,通过url去传,显得很臃肿,而且get的传递内容长度有限制。于是就想到用post的方式传递,问题在于open方法不能设置请求方式,一般网页的post都是通过form来实现的。如果仅仅模拟form的提交方式,那么open方法里那种可设置窗体属性的参数又不能用。最后想办法
postMessage可以解决跨域的传值问题,一般可以认为是父页面向子页面传递消息。 发送数据(父页面): otherWindow.postMessage(message, targetOrigin, [transfer]); otherWindow:其他窗口的一个引用,可以是window.open(‘xxx’)、window.opener等等(目前只用过这两种...
postMessage 是 html5 引入的API,postMessage()方法允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档、多窗口、跨域消息传递,多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案。 一、Window postMessage() 方法介绍 postMessage() 方法用于安全地实现跨源通信。(只有同源脚本才能相互通信,window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。) 1、语法:o
父页面向子页面传输相对容易,而子页面回传比较困难,尤其是回传再加上跨域,就是难上加难了。如果不涉及跨域使用window.opener.父方法名(回传参数)就可以调用父页面的函数。如果有跨域时,该方法会报错。而window.postMessage() 可以成功传递,方法如下: 1、父页面a.htmlwindow.open("b.html",'_blank',); window.addEvent...
window.opener 实际上就是通过window.open打开的窗体的父窗体。 比如在父窗体parentForm里面 通过 window.open("subForm.html"),那么在subform.html window.opener就代表parentForm,可以通过这种方式设置父窗体的值或者调用js方法。 如:1,window.opener.test(); ---调用父窗体的test()方法 Window postMessage() 方法 postMessage() 方法用于安
当使用Vue与Spring Boot结合使用时,通过axios进行post请求时出现传值为空的情况,可能是以下几个原因: 1. 参数未正确设置:在进行post请求时,需要使用axios的`data`属性来传递参数,而不是使用`params`属性。确保在axios的post请求正确设置了请求的参数。 2. 后端接收参数的方式不正确:在Spring Boot后端代码,使用`@RequestBody`注解来接收前端传递的参数,而不是使用`@RequestParam`注解。`@RequestBody`注解将请求体的内容与后端方法的参数绑定在一起,确保后端能够正确接收到前端传递的参数。 3. 参数名不匹配:确保前端传递的参数名与后端接收参数的变量名相匹配。在前端Vue代码,检查传递给post请求的参数名是否正确和后端代码定义的参数名一致。 4. 请求头未设置正确:在进行post请求时,可能需要设置请求的Content-Type为`application/json`或`application/x-www-form-urlencoded`。检查axios的请求头是否正确设置了Content-Type,确保与后端代码相匹配。 5. 跨域问题:如果前端Vue项目与后端Spring Boot项目部署在不同的域名或端口上,可能会存在跨域问题。在后端代码,可以通过`@CrossOrigin`注解来解决跨域问题。 综上所述,解决vue springboot axios post方法传值为空的问题需要检查参数设置、后端接收方式、参数名匹配、请求头设置和跨域等方面的问题。