四种方式实现不同页面之间的通信——前端

1,774 阅读2分钟

背景

A页面处理好本页面的数据后需要传递给到B页面,B页面需要根据A页面传递的数据做出相应的处理或者发出请求等操作。

1.通过URL传递

b页面基于a页面,通过window.open或window.location打开,可以将传递的数据放在url里

b页面打开后,通过拿url的参数拿到a页面的数据,实现数据传递

//a.html
<script>
const data = "this data from page a"
window.local = "http://localhost:3000/b.html?data=" + data
</script>

//b.html
<script>
function get_url(name) {
    let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    let r = window.location.search.substr(1).match(reg);
    if (r != null) {
        return decodeURIComponent(r[2]);
    };
    return null;
 }
 let data = get_url("data")
 console.log(data)  //this data from page a
</script>

这种方式的缺点也比较明显:url的长度有所限制,超出长度限制后会报错(414)

2.通过postMessage

postMessage可以向指定窗口发送信息,只需要写窗口监听message事件即可

//a.html
<iframe id="iframe" src="b.html" onload="load()" />
function load () {
  const iframe = document.getElementById("iframe").contentWindow
  iframe.postMessage("this data from page a", "/")  //第一个参数的数据,第二个参数是目标窗口所在的源
  window.onmessage = e => {  //监听message事件
    console.log(e.data)
  }
}
//同源下的b.html,也就是嵌在a页面的iframe里的
window.onmessage = e => {
  console.log(e.data)    //会打印在a页面的窗口,但b页面会收到this data from page a
}
//通过open打开窗口也是一个原理,window.open会返回一个对象
//通过该对象向opener发送(需要等opener打开并加载完)

3.通过localStorage

localStorage遵循同源策略,同时也持久储存,同源下一个页面设置,整个源的页面都能访问到

不用sessionStorage是因为即使是同源,窗口(标签页)不一样,sessionStorage也不能被访问到

//a.html (http://localhost:3000/a.html)
localStorage.setItem("a", "this is a")
//b.html (http://localhost:3000/b.html)
const data = localStorage.getItem("a")
console.log(data)  //this is a

4.通过Web SharedWorker

SharedWorker是个构造函数,可以创建一个执行指定 url 脚本的共享 web worker(点击跳转到MDN)

通过SharedWorker不同窗口或不同标签页可以共享同一脚本的内容

指写url脚本需要单独建立一个文件(worker.js)

//worker.js
let data = ""
onconnect = e => {  //onconnect事件,监听页面(线程)的连接
  const port = e.ports[0]
  port.start()
  port.onmessage = e => {
    if(e.data === "get"){
      port.postMessage("data")    //向页面(线程)里通过port监听message的发送消息
    } else {
      data += e.data
    }
  }
}
//a.html
<button onclick="triggle()">a页面修改</button>
let w = null;
if(!w) {
  w = new SharedWorker("./worker.js")    //指定url脚本,此处放在与a.html同级
  w.port.start()    //连接
}
let port = w.port
port.onmessage = function (e) {    //监听worker脚本发送的message
  console.log(e.data)
}
function triggle () {
  port.postMessage("a页面修改")    //向worker脚本发送信息
}
//b.html
<button onclick="triggle()">b页面获取</button>
let w = null;
if(!w) {
  w = new SharedWorker("./worker.js")
  w.port.start()
}
let port = w.port
port.onmessage = function (e) {
  console.log(e.data)  //或a页面点击了按钮,b页面获取则会打印a页面修改
}
function triggle () {
  port.postMessage("a页面修改")
}

SharedWorker在js线程外独立开启另一条线程,不影响主线程的同时在后台执行.

凡是通过SharedWorker连接同一个 url脚本的页面(线程)都可以收发worker的数据,但这些页面(线程)都要是同源的

以上