1. 什么是跨域?
跨域是一个比较常见的问题,简单来说就是当我们在一个页面中请求其他域名下的资源时,会受到浏览器的限制,这种情况就叫做跨域。跨域是出于安全考虑,防止非法获取用户的敏感信息或者在用户不知情的情况下收集用户信息。
1.1 跨域分类
跨域分为以下几种:
域名不同
端口不同
协议不同
子域名不同
其中,域名、端口、协议都不相同就是完全跨域,反之就不叫跨域。
2. iframe 跨域的情况
通常情况下,在同一个页面内,iframe 访问同源的内部资源不受限制,但是跨域的时候就会出现问题。
2.1 同源策略与 iframe
同源策略是浏览器的一种安全机制,主要限制了脚本(例如:JavaScript)在一个源的上下文中执行与使用来自不同源的资源。
iFrame 是 HTML5 中添加的一个新的元素,它可以让我们在一个页面内嵌入另一个页面,并且在该页面中显示,并且可以通过 JavaScript 来控制和访问嵌入的页面。
然而,由于同源策略的限制,在 iframe 中访问跨域的资源,例如:JavaScript、图片等都会受到限制。
例如,在页面 A 中嵌入页面 B 的 iframe 中,当页面 B 中的 JavaScript 试图访问页面 A 的资源时,会出现跨域的情况。
2.2 iframe 跨域的原理
在同一个域名下的网页之间,由于同源策略的限制,可以通过JavaScript 相互通信。但当一个子窗口与窗口的父窗口,或者两个不同的子窗口,他们之间的协议、主机、端口任意一个不同,都属于不同的域名,此时便产生了跨域问题。
当 iframe 在 A 网站内,通过 JavaScript 访问 B 网站时,浏览器会阻止这条 JavaScript 访问。
在同一域名下,我们可以通过 window.parent 来判断当前的 iframe 是不是和页面同源:
if (window.parent.location.href === window.location.href) {
console.log('同域')
} else {
console.log('跨域')
}
当在 iframe 中访问其他域名时,可以使用 window.postMessage 方法来进行通信,它可以跨窗口传递消息,从而在不同的页面或者 iframe 之间传递信息。在不同的页面之间,postMessage 方法可以在单向、双向等多种方式下进行通讯。
2.3 iframe 跨域常见问题
2.3.1 iframe 中跳转不刷新问题
iFrame 中页面 A 跳转到了页面 B,但是页面 B 内容变化之后,又回到了页面 A,此时页面 B 的变化并未被更新。
原因在于,页面 B 在跳转时,只是修改了 iframe 的 src 属性,而没有刷新真正嵌入 iframe 的内容。所以在跳回页面 A 时页面 B 内容并未更新。
如果需要刷新页面 B,可以添加时间戳参数或者随机数参数。每次跳转时,携带不同的时间戳参数就可以避免缓存,从而进行刷新。
2.3.2 iframe 无法获取父级页面元素问题
经常出现这样的场景,就是在 iframe 中需要获取父级页面的元素 DOM,但是一直获取不到。
原因在于,同源策略限制了 iframe 内部的 JavaScript 只能访问本身的 DOM,而无法访问父级页面中的 DOM。
解决办法是使用 window.postMessage 方法来在 iframe 和父级页面之间传递消息,使得两者之间能够进行双向通信。
2.3.3 iframe 宽度高度自适应问题
在跨域的情况下,由于无法获取到子页面的高度和宽度,所以 iframe 的高度和宽度也就无法实现自适应,需要手动进行计算和设置。
解决方案可以使用 JavaScript 计算 iframe 内容的实际高度,然后动态设置 iframe 的高度。
结论
在浏览器的安全限制下,iframe 的跨域访问受到了很多限制。通过了解 iframe 跨域的原理和常见问题,以及使用 postMessage 方法来解决通信问题,可以使我们更加完整地了解 iframe 的使用,更好地实现 iframe 的功能。