深入浅出iframe

news/2025/2/25 8:29:09

前言

说起iframe,大家都会觉得很嫌弃或者很不愿接近,原因大概都是:能耗高,安全问题,spider不喜欢它...也有(不少)同学内心独白就是:不!这很low很dirty,我才不想用惹!但是我们必须的承认iframe之强大,很多时候我们都会(不得不)使用它,真的素又爱又恨呐-8-

今天就在这里和大家一起好好讨论一下iframe。

iframe基本概念

我们先看一个?

javascript">javascript"><iframe src="demo.html" height="300" width="500" name="demo" scrolling="auto" sandbox="allow-same-origin"></iframe> 

iframe的一些基本属性:

  • src iframe页面地址,有同域跨域之分
  • height iframe高度
  • width iframe宽度
  • name iframe命名,可通过window.frames[xxx]被调用
  • scrolling iframe滚动模式
  • sandbox html5新特性,用于限制iframe的功能

使用iframe的正确姿势

我们可以通过contentWindowcontentDocument两个API获取iframe的window对象和document对象。

javascript">javascript">let iframe = document.getElementById('demo');
let iwindow = iframe.contentWindow; // 获取iframe的window对象 let idoc = iframe.contentDocument; // 获取iframe的document对象 

刚刚我们提到了iframe的name属性,我们也可以通过window.frames[iframeName]来调用iframe。

javascript">javascript">let iframe = window.frames['demo']

iframe使用父级内容的正确姿势

我们通过window.selfwindow.parentwindow.top这三个属性分别获取自身window对象,父级window对象,顶级window对象。

看图说话


 
iframe1.self === iframe1
iframe1.parent === iframe2
iframe2.parent === window
iframe1.top === window

同域/跨域

什么是同域什么跨域咧?同域跨域的区别在哪咧?我们一般会使用iframe来进行父子页面的通信,然鹅父子页面是否同域决定了它们之间能否进行通信。

js遵循同源策略,即同协议,同域名,同端口号,否则都算跨域。

同源策略 是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。实际上,这种策略只是一个规范,并不是强制要求,各大厂商的浏览器只是针对同源策略的一种实现。它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。

跨域 简单的来说,指的是两个资源非同源。出于安全方面的考虑,页面中的JavaScript在请求非同源的资源时就会出 跨域问题 ——即跨域请求,这时,由于同源策略,我们的请求会被浏览器禁止。也就出现了 我们常说的 跨域 问题。

通过这个图可以进一步帮助我们理解同域和跨域。

 

iframe跨域通讯之document.domain

对于主域相同子域不同的两个页面,我们可以通过document.domain + iframe来解决跨域通信问题。

举个?,网页a(http://www.easonwong.com)和网页b(http://script.easonwong.com),两者都设置document.domain = 'easonwong.com'(这样浏览器就会认为它们处于同一个域下),然后网页a再创建iframe上网页b,就可以进行通信啦~!

网页a

javascript">javascript">document.domain = 'easonwong.com';
var ifr = document.createElement('iframe'); ifr.src = 'http://script.easonwong.com'; ifr.style.display = 'none'; document.body.appendChild(ifr); ifr.onload = function(){ let doc = ifr.contentDocument || ifr.contentWindow.document; // 在这里操纵b.html }; 

网页b

javascript">javascript">document.domain = 'easonwong.com';

iframe跨域通讯之postMessage

postMessage是html5的新特性,具体介绍不在此赘述。

postMessage介绍

MDN postMessage

兼容性 IE8以上

can I use

我们可以通过html5这个新特性进行iframe间的跨域通信,使用postMessage进行数据传递,通过Message监听通信事件。举个?

网页a

javascript">javascript">document.domain = 'easonwong.com';
var ifr = document.createElement('iframe'); ifr.src = 'http://script.easonwong.com'; ifr.style.display = 'none'; document.body.appendChild(ifr); // 发送数据 ifr.postmessage('hello, I`m a', 'http://script.easonwong.com'); 

网页b

javascript">javascript">// 监听message事件
window.addEventListener('message', receiver, false); function receiver(e) { if (e.origin == 'http://www.easonwong.com') { if (e.data == 'hello, I`m a') { e.source.postMessage('hello, I`m b', e.origin);信息 } } } 

iframe实现JSBridge

在移动端Hybrid混合模式中经常用到JSBridge进行JS和Native之间的通信,其中我们可以通过iframe的方式实现JS调用Native的方法。

以上提到的方法就是URL SCHEME拦截。

URL SCHEME是一种类似于url的链接,是为了方便app直接互相调用设计的,形式和普通的 url 近似,主要区别是 protocol 和 host 一般是自定义的,例如: easonwong://hh/url?name=easonwong,其中protocol是easonwong,host则是hh。

我们通过创建一个iframe(src设为我们自定义的URL SCHEME)来发送请求,然后Native那边可以拦截到请求并获取其中带有的参数,即可进行后续的操作。

想了解更多具体的关于JSBridge的内容,可以阅读我的JSBridge学习笔记~

iframe的其他用途

  • 用iframe进行异步请求

在很久很久很久以前,久到ajax还没出现的时候,人们会用iframe来进行异步请求。大概就是异步创建iframe,然后后台返回数据在iframe中,我们在从里面获取数据。

例如在我做过的一个项目中,通过iframe.src传入一个文件下载地址,实现无需打开新窗口下载文件。

  • 引用/展示第三方内容

  • 需要独立样式和带有交互的内容,例如幻灯片

  • sandbox沙箱隔离

  • 历史记录管理

iframe的安全问题

iframe小广告

很让我们讨厌iframe的一点,就是很多*网站都会有各种让人防不胜防的小广告,它们大多就是用通过iframe实现的,本来想点击某个播放按钮,结果马鸭直接跳几十跳不知道去了哪个新世界去了。

更讨厌的一种情况是,可能不知道哪天用户突然拿刀过来,说我们的项目页面里出现了野鸡广告,说我们在消费他们,一脸懵逼的我们觉得十分无辜。实际上就是我们的页面被运行商劫持了,被挂上了注入了不知名的野鸡广告。

所以我们一定要注意在用iframe的同时,要防止我们被iframe了。

防嵌套页面操作

前端领域,我们可以通过window.top来防止我们页面被嵌套。

javascript">javascript">if(window != window.top){
    window.top.location.href = myURL; } 

或者通过window.location.host来检测是否跨域了

javascript">javascript">if (top.location.host != window.location.host) {
  top.location.href = window.location.href;
}

而后端也可以做对应的防范措施,通过设置X-Frame-Options响应头来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。

CSP

内容安全策略(CSP)用于检测和减轻用于 Web 站点的特定类型的攻击,例如 XSS 和数据注入等。

MDN CSP

通过CSP配置sandbox和child-src可以设置iframe的有效地址,它限制适iframe的行为,包括阻止弹出窗口,防止插件和脚本的执行,而且可以执行一个同源策略。

用法

  • 我们可以在html头部中加上<meta>标签
    <meta http-equiv="Content-Security-Policy" content="child-src 'unsafe-inline' 'unsafe-eval' www.easonwong.com"> 
  • 或者通过HTTP头部信息加上Content-Security-Policy字段

转载于:https://www.cnblogs.com/dingxingxing/p/10739375.html


http://www.niftyadmin.cn/n/712990.html

相关文章

ios 消息推送原理

一、消息推送原理&#xff1a; 在实现消息推送之前先提及几个于推送相关概念&#xff0c;如下图1-1&#xff1a; 1-1 1、 Provider&#xff1a;就是为指定IOS设备应用程序提供Push的服务器&#xff0c;&#xff08;如果IOS设备的应用程序是客户端的话&#xff0c;…

qt如何优化程序内存_Python基础教程:(小窍门)如何优化Python占用的内存

概述如果程序处理的数据比较多、比较复杂&#xff0c;那么在程序运行的时候&#xff0c;会占用大量的内存&#xff0c;当内存占用到达一定的数值&#xff0c;程序就有可能被操作系统终止&#xff0c;特别是在限制程序所使用的内存大小的场景&#xff0c;更容易发生问题。下面我…

python生成表格乱码_Python程序中使用SQLAlchemy时出现乱码的解决方案

今天对clubot进行了升级, 但是导入数据后中文乱码, 一开是找资料说是在创建引擎的时候添加编码信息:?但是这并不行, 然后查看表信息:?发现原来创建表的时候用的latin1编码, 而老的表是用utf-8编码创建的, SQLAlchemy中并没有发现有创建表时指定指定编码的方法. 所以只能在MyS…

ZZULIOJ-1092,素数表(函数专题)(Python)

题目描述&#xff1a; 输入两个正整数m和n&#xff0c;输出m和n之间的所有素数。 要求程序定义一个prime()函数和一个main()函数&#xff0c;prime()函数判断一个整数n是否是素数&#xff0c;其余功能在main()函数中实现。 int prime(int n) { //判断n是否为素数&#xff0…

计算机硬件的组成要素

不清楚cpu&#xff08;处理器&#xff09;、内存、I/O的小伙伴们&#xff0c;重点来了&#xff01; 计算机硬件的主要组成要素如下图&#xff1a;CPU是计算机的大脑&#xff0c;在其内部可对数据执行运算并控制内存和I/O。内存用于存储指令和数据。I/O负责把键盘、鼠标、显示器…

python 短路运算符_Python中三目计算符的正确用法及短路逻辑

今天在看别人代码时看到这样一种写法, 感觉是个挺容易踩到的坑, 搞清楚后写出来备忘.短路逻辑Python中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接看代码print True and 1# 1print True or 1# Trueprint False and 1# Falseprint F…

ZZULIOJ-1093,验证哥德巴赫猜想(函数专题)(Python)

题目描述&#xff1a; 哥德巴赫猜想大家都知道一点吧。我们现在不是想证明这个结论&#xff0c;而是对于任给的一个不小于6的偶数&#xff0c;来寻找和等于该偶数的所有素数对。做好了这件实事,就能说明这个猜想是成立的。 要求程序定义一个prime()函数和一个main()函数&#x…

ios多线程之GCD

介绍&#xff1a; Grand Central Dispatch 简称&#xff08;GCD&#xff09;是苹果公司开发的技术&#xff0c;以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统。这建立在任务并行执行的线程池模式的基础上的。它首次发布在Mac OS X 10.6 &#xff0c;iOS 4及以…