您的位置:

iframe跨域问题详解

一、嵌入别人的网站

在我们平常的网站开发中,经常会用到将其他网站的页面或内容嵌入到我们自己的网站中,这时候会使用到iframe标签。如下所示:

<iframe src="http://www.otherwebsite.com" width="100%" height="600"></iframe>

但是,如果我们将一个非同源的网站嵌入到我们的网站中,就会出现跨域问题。

二、iframe为什么支持跨域

iframe标签支持跨域是因为iframe在浏览器中是作为一个独立的页面存在的,它有自己的window对象、document对象和location对象。

三、iframe跨域问题

当我们在一个网站中使用iframe嵌入来自不同源的网页时,会出现访问限制的问题。比如,在A网站中嵌入B网站的页面,如果B网站有对应访问限制,那么A网站就无法访问B网站页面的内容。这是因为浏览器秉承同源策略的原则,只有在协议、域名、端口这三个方面相同的情况下才可以访问。

四、iframe跨域加载页面

在iframe的src属性中可以指定一个跨域的页面来进行加载,如下所示:

<iframe src="http://www.otherwebsite.com" width="100%" height="600"></iframe>

但是,如果跨域页面的服务器设置了相关的访问控制,可能导致页面无法加载,这时需要在服务器端进行相应的设置以允许访问。

五、iframe跨域登录

在一个网站中使用iframe嵌入来自不同源的网站时,如果需要在iframe中进行登录操作,需要使用到postMessage这个API来进行消息的传递。

window.parent.postMessage("login", "http://www.otherwebsite.com");

在被嵌入的网站中,需要添加相应的监听事件来接收消息并进行处理。

window.addEventListener('message',function(evt) {
    if(evt.origin !== 'http://www.mywebsite.com') return;
    if(evt.data === 'login') {
        // 处理登录操作
    }
 });

六、iframe跨域高度自适应

在iframe中嵌入一个不同源的网页时,可能会出现高度无法自适应的问题。解决这个问题可以使用window.postMessage API来进行消息的传递。iframe中的页面需要先获取自身的高度并发送给父页面。

let height = document.documentElement.scrollHeight;
window.parent.postMessage(height, "http://www.parentwebsite.com");

在父页面中需要添加相应的监听事件来接收消息并进行处理,将iframe的高度设置为接收到的高度即可。

window.addEventListener('message',function(evt) {
    if(evt.origin !== 'http://www.childwebsite.com') return;
    let height = evt.data;
    document.getElementById('iframe').style.height = height + 'px';
 });

七、iframe跨域获取内容

在一个网站中使用iframe嵌入来自不同源的网站时,如果需要获取嵌入页面中的内容,需要使用到window.postMessage API。

window.frames['iframe'].postMessage("getContent", "http://www.childwebsite.com");

在被嵌入的网站中,需要添加相应的监听事件来接收消息并进行处理。

window.addEventListener('message',function(evt) {
    if(evt.origin !== 'http://www.parentwebsite.com') return;
    if(evt.data === 'getContent') {
        let content = document.getElementById('content').innerHTML;
        window.parent.postMessage(content, "http://www.parentwebsite.com");
    }
 });

八、iframe跨域解决方案

解决iframe跨域问题的方式有以下几种:

1、使用postMessage API进行消息传递;

2、在服务器端设置Access-Control-Allow-Origin头信息,允许跨域访问;

3、使用JSONP方式获取数据;

4、在父页面中使用代理页面,将请求发送给代理页面,代理页面再将请求发送给另一个域名的服务器,在代理页面中处理返回结果并将结果发送给父页面。

九、iframe跨域修改样式

在一个网站中使用iframe嵌入来自不同源的网站时,需要修改嵌入页面的样式时,可以使用postMessage API进行消息传递,将需要修改的样式信息传递给iframe页面。

window.frames['iframe'].postMessage({type: 'updateStyle', cssText: 'body {background-color: red;}'}, "http://www.childwebsite.com");

在被嵌入的网站中,需要添加相应的监听事件来接收消息并进行处理。

window.addEventListener('message',function(evt) {
    if(evt.origin !== 'http://www.parentwebsite.com') return;
    if(evt.data.type === 'updateStyle') {
        let cssText = evt.data.cssText;
        let style = document.createElement('style');
        style.innerHTML = cssText;
        document.head.appendChild(style);
        window.parent.postMessage('style updated', "http://www.parentwebsite.com");
    }
 });