相关文章推荐
完美的双杠  ·  陈强《第10章 ...·  8 月前    · 
俊逸的西瓜  ·  Linux远程桌面-阿里云·  2 年前    · 

随着业务的发展,自然地会有一些公共的业务被抽离成为公共组件供各个项目使用。但是由于各个项目用到的技术栈都有所不同,所以这个公共组件就不能方便地被引用了。为解决这个问题,我们把这个组件写成了单独的页面挂到一个域名下,其他项目采用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

★★ 解释下 let 和 const 的块级作用域 ★★★★ 说说你对执行上下文的理解 ★★★ 对闭包的看法,为什么要用闭包?说一下闭包的原理以及应用场景?闭包的 this 指向问题? ★★★ 简述闭包的问题以及优化 ★★★ 如何确定 this 指向?改变 this 指向的方式有哪些? ★★★ 介绍箭头函数的 this
在父页面中写入iframe标签,其中src值为需要跨域访问的页面地址<iframe ref="iframe" src="http://xxx/index.html" name="iframeDemo" width="100px" height="0px" frameborder="0" scrolling="no" style="opacity:0;" ></iframe> 在父页面的方法中写入document.querySelector('iframe').contentWindo
使用 iframe 实现跨域访问是一种常见的技术。通过将另一个域的内容嵌入到当前页面的 iframe 中,可以实现跨域访问。这种方法通常用于在网页中嵌入来自不同域的内容,比如嵌入其他网站的地图、视频或其他资。 但需要注意的是,由于安全原因,浏览器通常会限制跨域访问,因此在使用 iframe 实现跨域访问时,需要确保被嵌入的内容允许跨域访问,或者采取其他安全措施来确保安全性。使用 iframe 实现跨域访问是一种常见的技术。通过将另一个域的内容嵌入到当前页面的 iframe 中,可以实现跨域访问。
iframe页面之间嵌套,iframe页面在不在同一域名(什么是不同域),由于浏览器做安全限制,不允许跨域调用。 在HTML5之后提供了iframe之间通信方法,可以实现不同域之间传输数据。 子frame向顶端发送消息实现跨域方法调用: 子页面定义请求调用的方法列表 newTop ,这里测试子页面给top顶层页面发送消息 var newTop = { setStatus : function(){ sendOrigin(arguments); var originFunctionC
原型和原型链 原型:构造函数的 prototype 属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型。也即,每个构造函数的实例都有一个原型,叫原型对象,由实例对象的内置属性_proto_指向。每个原型都有一个 constructor 属性指向关联的构造函数。 原型用法:构造函数创建的实例可以访问实例的属性和方法,也可以访问原型的属性和方法。对于原型只能访问自己的属性和方法。考虑这一特性,如果对象公有的属性和方法,我们可以添加到原型上面,对象需要的时候直接访问原型的属性和方法就可以。
具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 码的编译器 javac,还包含了很多 java 程序调试和分析的工具。简单来说:如果你需要运行 java 程序,只需安装 JRE 就可以了,如果你需要编写 java 程序,需要安装 JDK。== 解读对于基本类型和引用类型 == 的作用效果是不同的,如下所示:代码示例:[](javascript:void(0)?? [](javascript:void(0)??代码解读:因为 x 和 y 指向的是同一个引用,所以 == 也是 true,而
假设A.html 与 b.htmldomain都是localhost (同域) A.html中iframe 嵌入 B.html,name=myframe A.html有js function fMain() B.html有js function fIframe() 需要实现 A.html 调用 B.html 的...
前端代码规范最佳实践:eslint + prettier + editorconfig + lint-staged + vscode的settings.json文件 CSDN-Ada助手: 哇, 你的文章质量真不错,值得学习!不过这么高质量的文章, 还值得进一步提升, 以下的改进点你可以参考下: (1)提升标题与正文的相关性。 Taro笔记 CSDN-Ada助手: 哇, 你的文章质量真不错,值得学习!不过这么高质量的文章, 还值得进一步提升, 以下的改进点你可以参考下: (1)提升标题与正文的相关性。 javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法 CSDN-Ada助手: 哇, 你的文章质量真不错,值得学习!不过这么高质量的文章, 还值得进一步提升, 以下的改进点你可以参考下: (1)提升标题与正文的相关性。 px、%、em、rem、vw、vh区别 CSDN-Ada助手: 前端构建工具Vite的优点是什么呢?