一、嵌入别人的网站
在我们平常的网站开发中,经常会用到将其他网站的页面或内容嵌入到我们自己的网站中,这时候会使用到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");
}
});