背景
有一个需求,网站1点击按钮后跳转到页面2,页面1和页面2的域名不同,并且需要传递参数A,再
那么最简单的就是 在url上带参数A 比如 https://xx.com?A=xxx ,从url上的queryParam上就能获取参数
但很可惜,参数A由于是敏感数据,不能通过get请求传递,否则每个传输层(Nginx、Tomcat)都会存留该数据。
首先就找不通过url传递参数的方式,那么有的同学就会问,为什么不能把参数放请求体里,因为get方式实际也是支持请求体传参的,但他是打开链接啊!
方案一: postMessage
window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口号(443 为 https 的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
其实之前用于iframe父子页面的通信传参,纯前端操作,只要定义好发送的来源和接收origin,则可安全传输参数。
页面1:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Page 1</title>
</head><body><!-- 创建一个 a 链接,点击时打开新的标签页 --><a id="openPage2" href="page2.html" target="_blank">Open Page 2</a><script>document.getElementById('openPage2').addEventListener('click', function (e) {// 阻止默认的链接跳转行为e.preventDefault();// 打开新的标签页const newWindow = window.open('page2.html', '_blank');if (newWindow) {// 监听新窗口的加载完成事件newWindow.onload = function () {// 定义要传递的参数const data = { a: 'xx' };// 使用 postMessage 方法将参数传递给新窗口newWindow.postMessage(data, '*');};}});</script>
</body></html>
页面2
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Page 2</title>
</head><body><h1>Page 2</h1><script>// 监听 message 事件,接收从页面 1 传递过来的参数window.addEventListener('message', function (event) {// 检查消息来源,确保是我们期望的消息if (event.origin === window.origin) {const data = event.data;console.log('Received data:', data);// 可以在这里处理接收到的参数if (data.a) {console.log('Value of a:', data.a);}}});</script>
</body></html>
综上,原页面需要获取下一个tab页的window对象,并且通过这个window对象发起postmessage方法发送参数。但是打开页面2时,页面2不一定执行完监听逻辑。
关于安全性及兼容性参考: window.postMessage - Web API | MDN
所以逻辑优化成
页面2如何获取到页面1的window对象呢,就使用window.opener即可
方案二:hash
安全的本质是使用了get请求,参数层层记录,如果将参数放到#后,及hash则浏览器会识别为页面锚点,仅给页面使用,就不会传递到服务器上。
即 https://xx.com#A=xx 使用location.hash 获取参数。
最终选了方案二