概念
Iframe(Inline Frame)是HTML中的一个标签,用于在网页中嵌入另一个网页。它可以在一个网页中显示另一个网页的内容,类似于一个窗口或容器。Iframe的作用是允许在一个网页中显示来自不同源的内容,实现了网页的嵌套和跨域通信。
Iframe的语法如下:
<iframe src="URL" width="width" height="height"></iframe>
其中,src属性指定要嵌入的网页的URL,width和height属性指定Iframe的宽度和高度。
Iframe的作用有以下几个方面:
-
嵌入其他网页:通过Iframe,可以将其他网页嵌入到当前网页中,实现了网页内容的复用和组合。例如,可以在一个博客页面中嵌入视频或地图等外部内容。
-
实现跨域通信:由于Iframe可以加载来自不同源的网页,因此可以通过Iframe实现不同域之间的通信。这在一些需要跨域操作的场景中非常有用,例如在一个网页中嵌入第三方的登录界面。
-
隔离网页内容:Iframe可以将嵌入的网页与当前网页进行隔离,避免相互之间的影响。这对于一些不可信的网页或广告内容非常重要,可以保护主页面的安全性。
总结以上内容,Iframe是HTML中的一个标签,用于在网页中嵌入另一个网页。它可以实现网页的嵌套和跨域通信,具有嵌入其他网页、实现跨域通信和隔离网页内容的作用。
浏览器同源机制
浏览器的同源策略是一种安全机制,用于限制一个网页文档或脚本如何与另一个来源的资源进行交互。同源策略有助于防止恶意网站通过脚本等方式访问用户的敏感数据,确保用户信息的安全性。
同源策略规定了以下三个要素:
- 协议(Protocol) :指URL中的
http://或https://等协议部分。 - 域名(Host) :指URL中的域名部分,包括子域名。
- 端口(Port) :指URL中的端口部分,用于标识网络服务的端口号。
如果两个 URL 在这三个要素上完全相同,则被认为是同源的。如果不同,就会受到同源策略的限制。
同源策略的限制主要包括以下几个方面:
- JavaScript 脚本的限制:来自不同源的 JavaScript 脚本不能相互访问对方的内容。
- DOM(文档对象模型)的限制:来自不同源的网页无法获取对方的 DOM 对象。
- Cookie、LocalStorage 和 IndexedDB 的限制:来自不同源的网页无法访问对方的 Cookie、LocalStorage 和 IndexedDB 存储。
- AJAX 请求的限制:使用 XMLHttpRequest 发起的 AJAX 请求受到同源策略的限制,无法向不同源的服务器发起请求。
同源策略的作用是确保浏览器只能在用户明确的授权下,与同一个源的资源进行交互,从而提高了用户信息的安全性。
Iframe与父页面之间的通信
将父应用程序作为主应用程序加载到浏览器中,并在其中设置 iframe,通过 iframe 的 src 属性加载另一个网页。
Iframe 与 父页面同源
父页面的URL:www.aa.com iframe的URL: www.aa.com/child 两者同源,根据同源策略,如果我们有另一个窗口的引用,例如由 window.open 创建的弹出窗口或 内的窗口,并且该窗口来自同一源,那么我们就可以完全访问该窗口。这种情况下,我们可以通过window对象来实现父子的通信。
下面是一个具体示例,演示了如何使用window对象在IFrame与父页面之间进行通信:
//1. 父页面 ——> iframe
// iframe应用中
// 绑定方法到Window
window.childCallback = function() {
console.log('来自父页面');
}
// 父页面中
// 加载iframe
<iframe id='iframe' src="http://www.aa.com/child"/>
// 可以直接获取iframe的Window并调用对应的方法
const iframe = document.getElementById("iframe");
iframe.contentWindow.childCallback();
//2. iframe ——> 父页面
// 父页面中
// 绑定方法到Window
window.parentCallback = function() {
console.log('来子iframe');
}
// iframe应用中
// 直接获取parent的Window并调用对应的方法
window.parent.parentCallback();
Iframe 与 父页面不同源
父页面的URL:www.parent.com iframe的URL: www.child.com 两者同源,这种情况下,我们可以使用window.postMessage() 方法安全地启用 Window 对象之间的跨域通信,实现页面和嵌入其中的 iframe 之间相互通信。
下面是一个具体示例,演示了如何使用postMessage()方法在IFrame与父页面之间进行通信:
// iframe ——> 父页面
// 在IFrame中的网页中发送消息给父页面
window.parent.postMessage('Hello from IFrame!', 'https://www.parent.com');
// 在父页面中监听message事件,接收来自IFrame的消息
window.addEventListener('message', function(event) {
if (event.origin === 'https://www.child.com') {
console.log('Received message from IFrame:', event.data);
}
});
// 父页面 ——> iframe
// 在IFrame中的网页中监听message事件,接收来自父页面的消息
window.addEventListener('message', function(event) {
if (event.origin === 'http://www.parent.com') {
var message = event.data;
console.log('Received message from Parent:', message);
// 立即发送消息回应给父页面
// event.source.postMessage('Hello, Parent!', event.origin);
}
});
// 父页面中
// 加载iframe
<iframe id='iframe' src="http://www.child.com"/>
// 父页面的网页中 发送消息给iframe
const iframeWindow = document.getElementById("iframe").contentWindow;
iframeWindow.postMessage("Hello from Parent", "*");///'*'或'http://www.child.com'
通过以上方法,IFrame与父页面之间可以实现灵活的通信,从而解决嵌入网页后的交互问题。
iframe 与 cookies
Cookie 是直接存储在浏览器中的小数据字符串。它们是 HTTP 协议的一部分,由RFC 6265规范定义。
Cookie 通常由 Web 服务器使用响应Set-CookieHTTP 标头设置。然后,浏览器会使用 HTTP 标头将它们自动添加到(几乎)对同一域的每个请求中Cookie。
最广泛的用例之一是身份验证:
- 登录后,服务器使用
Set-Cookie响应中的 HTTP 标头来设置具有唯一“会话标识符”的 cookie。 - 下次将请求发送到同一域时,浏览器将使用
CookieHTTP 标头通过网络发送 cookie。 - 这样服务器就知道是谁发出了请求。
我们还可以使用属性从浏览器访问 cookie document.cookie。
domain
domain=site.com 域定义了可以访问 cookie 的位置。但在实际操作中,这是有限制的。我们不能设置任何域。
没有办法让另一个二级域名访问 cookie,所以 other.com 永远不会收到 site.com 设置的 cookie。
这是一个安全限制,允许我们在 cookie 中存储敏感数据,这些数据只能在一个网站上使用。
默认情况下,cookie 只能在设置它的域中访问。请注意,默认情况下,cookie 不会与子域共享,如 forum.site.com。但这是可以改变的。如果我们想让 forum.site.com 等子域获得 site.com 设置的 cookie,这也是可以实现的.
// at site.com
// make the cookie accessible on any subdomain *.site.com:
document.cookie = "user=John; domain=site.com"
// later
// at forum.site.com
alert(document.cookie); // has cookie user=John
path
path=/mypath URL 路径前缀必须是绝对的。它能让该路径下的页面访问 cookie。默认情况下,它是当前路径。
如果使用 path=/admin 设置了 cookie,那么它在 /admin 和 /admin/something 页面上可见,但在 /home、/home/admin 或 / 上则不可见。
通常情况下,我们应该将路径设置为根:path=/,以便所有网站页面都能访问 cookie。如果未设置此属性,则使用此方法计算默认值。
secure
secure : 默认情况下,如果我们在 site.com 上设置了 cookie,那么它也会出现在 site.com 上,反之亦然。
也就是说,cookie 是基于域的,并不区分协议。
有了这个属性,如果在 site.com 上设置了 cookie,那么在通过 HTTP 访问同一网站(如 site.com)时,它就不会出现。因此,如果一个 cookie 包含敏感内容,而这些内容永远都不应该通过未加密的 HTTP 发送,那么安全标记就是正确的选择。
// assuming we're on https:// now
// set the cookie to be secure (only accessible over HTTPS)
document.cookie = "user=John; secure";