亲像爱情的限时批~
各位有想过该如何跟其他页面进行沟通吗?如果在A页面点击了一个按钮,能不能够让B页面发生变化或执行动作呢?别说不可能,今天要介绍的 PostMessage 便能够达成这样的效果。
一般来说,不同的页面要相互沟通的话,它们的 Domain 必须相同,然後通常就会使用 LocalStorage 搭配 storage
事件来进行沟通,但 PostMessage 神奇的地方就在於它可以越过这项限制,让我们甚至可以跟不同源的网站页面进行沟通,这样就能解决前端最讨厌的 CORS 问题了。
虽然 PostMessage 可以跨域沟通,不过当然也要对方愿意且有撰写对应的机制程序码,要不然世界就大乱了 XD
PostMessage API 底下就是只有 postMessage
这个 method,非常的单纯,却也无比强大,其中 otherWindow
所指的是「目前分页以外的 Window」,这个 Window 可以是利用 window.open
执行返回的 Window 物件,或是一个 iframe
元素的 contentWindow
,而也就是讯息要送达的目的地。
另外 postMessage
还必须传入两个参数:
const url = "https://maxleebk.com//2021/09/28/webApi/webApi-15/";
const otherPage = window.open(url);
otherPage.postMessage("Hi,Max", "https://maxleebk.com/");
以上面的例子来说,我们先利用 window.open
打开了一个作者本人的部落格分页,而该分页的 Window 已经被储存在 otherPage
中,再来我们就利用 postMessage
传递一个字传,并且利用 targetOrigin
来确保一定要是 https://maxleebk.com/
底下的页面才能真正接受到讯息。
你该注意:
targetOrigin
这个参数建议一定要传入并填妥,不然讯息有可能会被刻意拦截,导致无法预期的安全性问题。
讯息有传送的一方,自然也要有接收的一方,而接收方要顺利接到讯息的话,只要在 window
上监听 message
这个事件即可,而讯息的部分则会被放在 Event 物件的 data
属性里:
window.addEventListener("message", function (event) {
console.log(event.data);
});
所以只要你想传送的网站中,有打开一个这样的通道,那你就可以透过 PostMessage 来与之沟通,不过接收方也不可能所有的讯息都照单全收,要是我们今天身为接收方,那应该要像下方这样做一些防御。
在 Event 物件中还有一个 origin
属性,可以用来获取传送方的来源,所以我们可以利用它来过滤那些不在信任范围的网址:
window.addEventListener("message", function (event) {
// 如果讯息不是来自於 IT邦帮忙 那就不执行任何动作
if (event.origin !== "https://ithelp.ithome.com.tw") return;
console.log(event.data);
});
当然了,信息往来总不能只有单向,如果接收方要回信的话,只要利用 Event 物件中的 source
属性就可以进行讯息的传送:
window.addEventListener("message", function (event) {
if (event.origin !== "https://ithelp.ithome.com.tw") return;
console.log(event.data);
event.source.postMessage("hi,IT邦帮忙", event.origin);
});
透过 PostMessage 讯息的相互传递,我们就可以不受同源政策的限制,向其他网域的网页请求资料了,或利用讯息的格式判定来执行其他页面的动作等等...
window.addEventListener("message", function (event) {
axios.get("/user", event.data.id).then((res) => {
event.source.postMessage(res, event.origin);
});
});
window.addEventListener("message", function (event) {
window[event.data.method](); // 执行指定名称的全域函式
});
PostMessage API 是不是非常有趣又神奇呢?或许要遇到页面沟通的情境并不多,但千万忽略了它,等到遇到了,它会是非常强大的帮手,而且应用起来也相当简单,大家如果有兴趣,随手就能写个简单的范例。
<<: [Day15] Server - 中场来点 NGINX 设定
前言 既然可以使用grid-area为每个区域命名,并填入grid-template-areas中,...
在 CNN-based 的架构中,会使用三种不同的 CNN 架构: Basic CNN Multi-...
第二十二天 各位点进来的朋友,你们好阿 小的不才只能做这个系列的文章,但还是希望分享给点进来的朋友,...
简介 之前在kaggle上面学习到了很多Python应用在Machine Learning的方法 对...
今日题目 题目连结:20. Valid Parentheses 题目主题:String, Stack...