背景
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的数据,但这些页面(线程)都要是同源的