iframe的src可以引入任何源,但是二者如果想通信的话,必须是同源,如果是非同源,如何解决?

iframe的src可以引入任何源,但是二者如果想通信的话,必须是同源。

背景

随着业务的发展,自然地会有一些公共的业务被抽离成为公共组件供各个项目使用。但是由于各个项目用到的技术栈都有所不同,所以这个公共组件就不能方便地被引用了。为解决这个问题,我们把这个组件写成了单独的页面挂到一个域名下,其他项目采用iframe或者webview的方式去加载这个页面,从而实现功能的简单复用。
不过这过程中也产生了很多问题,比如通信跨域。以下我将会介绍我遇到的跨域问题以及一些解决方法。

场景

最近在做一个需求,需要用iframe引入一个别人封装好的类似视频播放器的东西。iframe里面有一个全屏的按钮,点击后需要页面让iframe全屏,由于受到同源策略的限制,iframe无法告诉页面全屏。

解决方法
1. 设置domain 该方法在mdn上已不推荐使用,而且已废弃

document.domain 是 JavaScript 中的一个属性,用于设置或获取当前页面的域名。

它的作用是允许在同一个域名下的不同子域之间进行跨域通信。默认情况下,不同子域之间的 JavaScript 代码是无法直接访问彼此的属性和方法的,这是出于安全考虑的限制。但是,如果将它们的 document.domain 设置为相同的值,就可以解除这个限制。

使用方法很简单,只需要在 JavaScript 中设置 document.domain 属性为相同的值即可。例如:

// 在父页面中设置 document.domain
document.domain = "example.com";

// 在子页面中也设置 document.domain
document.domain = "example.com";

这样,父页面和子页面就可以通过 JavaScript 代码进行跨域通信了。

需要注意的是,为了使用 document.domain 进行跨域通信,域名必须满足以下条件:

  • 主域名相同
  • 端口号相同
  • 协议相同

否则,浏览器将不允许使用 document.domain 进行跨域通信。

设置完之后,在a页面的window上挂载使iframe全屏的方法

// a页面
window.toggleFullScreen = () => {
    // do something
}

在b页面上可以直接获取到a页面的window对象并直接调用

// b页面
window.parent.toggleFullScreen()

但是这个值的设置也有一定限制,只能设置为当前文档的上一级域或者是跟该文档的URL的domain一致的值。如url为a.demo.com,那domain就只能设置为demo.com或者a.demo.com。因此,设置domain的方法只能用于解决主域相同而子域不同的情况。

2. postmessage

window.postMessage方法可以安全地实现跨源通信,写明目标窗口的协议、主机地址或端口就可以发信息给它。

// b页面
parent.postMessage(
    value,
    "http://a.demo.com"
);
// a页面
window.addEventListener("message", function( event ) {
    if (event.origin !== 'http://b.demo.com') return;
    toggleFullScreen()
 });

为了安全,收到信息后要检测下event.origin判断是否要收信息的窗口发过来的。

总结

通过以上的方法,我们就可以和iframe自由通信啦。

参考:iframe跨域的几种常用方法:https://juejin.cn/post/6844903831973675015

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
同源策略是一种浏览器安全机制,用于限制一个(域名、协议和端口)的文档或脚本如何与另一个的资进行交互。同源策略的目的是防止恶意网站通过脚本访问用户的敏感信息或执行恶意操作。 在同源策略下,一个的文档或脚本只能与同一的资进行交互,不能直接访问其他的资。这意味着,如果一个页面中包含一个来自不同源iframe元素,那么该iframe中的文档或脚本将无法直接访问父页面的DOM,也无法通过常规的方式与父页面进行通信。 然而,同源策略并不是绝对的,有一些方法可以绕过同源策略实现跨域访问,其中包括以下几种常见的方法: 1. JSONP跨域:通过动态创建`<script>`标签,将跨域请求的数据作为回调函数的参数返回到页面中。 2. document.domain + iframe跨域:当两个页面的域名相同但是子域不同,可以通过设置`document.domain`属性来实现跨域访问。 3. location.hash + iframe跨域:通过改变iframe的URL的hash值来传递数据,从而实现跨域通信。 4. window.name + iframe跨域:通过在iframe的`window.name`属性中存储数据,实现跨域通信。 5. postMessage跨域:通过使用`window.postMessage()`方法在不同窗口之间传递消息,实现跨域通信。 6. 跨域资共享(CORS):在服务器端设置响应头,允许指定的进行跨域访问。 7. nginx代理跨域:通过配置nginx服务器代理请求,实现跨域访问。 8. nodejs中间件代理跨域:通过使用nodejs中间件代理请求,实现跨域访问。 9. WebSocket协议跨域:通过WebSocket协议进行跨域通信。 总结起来,同源策略是浏览器的一种安全机制,限制了不同源之间的交互。但是通过一些特定的方法,可以实现跨域访问和通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

. . . . .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值