解决iframe跨域高度自适应问题

Author Avatar
Reborn 8月 21, 2018
  • 在其它设备中阅读本文章

背景

我在前面写博文的时候,有遇到一次需要嵌套别人的网页来做预览,我想到了用iframe标签,结果发现根本没法自适应高度??!!什么玩意,强迫症的我又走上了填坑之路。对,你没看错,又。。。。

iframe自适应高度

参考:完美解决Iframe高度自适应(兼容性好并且支持跨域)

经过一番搜索,终于找到了自适应高度的方法。
具体代码如下:

<script type="text/javascript">
 function SetCwinHeight(){
  var iframeid=document.getElementById("iframeid"); //iframe id
  if (document.getElementById){
   if (iframeid && !window.opera){
    if (iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight){
     iframeid.height = iframeid.contentDocument.body.offsetHeight;
    }else if(iframeid.Document && iframeid.Document.body.scrollHeight){
     iframeid.height = iframeid.Document.body.scrollHeight;
    }
   }
  }
 }
</script>
<iframe width="100%" id="iframeid" onload="Javascript:SetCwinHeight()" height="1" frameborder="0" src="www.xxx.com"></iframe>

然后。。。然后。。。没有然后,一点反应都没有??!!什么东西??我直觉告诉我很快就能搞定了,于是我继续填(wa)坑。

解决跨域问题

原来。。。是 js 的跨域问题在搞鬼(好吧,我承认我主学的不是前端😂)

跨域的解决方法有很多,我用的是document.domain+Nginx域名转发的方法,比较偷懒嗯😂。

这种方法只适用于在自己博客上插入iframe的情况,而且需要博客在自己的服务器上和拥有自己的域名。

废话不多说,我先说一下Nginx域名转发

Nginx域名转发

20180823更新:本节内容已转移到Nginx域名转发(反向代理)

document.domain

参考:

把 iframe 中src的网址转发到自己的域名后就可以用document.domain解决跨域问题啦!

document.domain是比较常用的跨域方法。实现最简单但只能用于同一个主域下不同子域之间的跨域请求,比如 foo.comimg.foo.com 之间,img1.foo.comimg2.foo.com 之间。只要把两个页面的document.domain都指向主域就可以了,比如document.domain='foo.com';
设置好后父页面和子页面就可以像同一个域下两个页面之间访问了。父页面通过ifr.contentWindow就可以访问子页面的window,子页面通过parent.windowparent访问父页面的window,接下来可以进一步获取dom和js。

<!-- foo.com/a.html -->
<iframe id="ifr" src="http://img.foo.com/b.html"></iframe>
<script> document.domain = 'foo.com';
function aa(str) {
    console.log(str);
}
window.onload = function () {
    document.querySelector('#ifr').contentWindow.bb('aaa');
} </script> 
<!-- img.foo.com/b.html -->

<script> document.domain = 'foo.com';
function bb(str) {
    console.log(str);
}

parent.aa('bbb'); </script>

总结

下面是我修改后的代码:

my.js

function SetCwinHeight(id) {
    document.domain='www.abc.com'
    var iframeid = document.getElementById(id); //iframe id
    if (document.getElementById) {
        if (iframeid && !window.opera) {
            console.log("iframeid:" + iframeid.contentDocument);
            if (iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight) {
                iframeid.height = iframeid.contentDocument.body.offsetHeight + 50;
            } else if (iframeid.Document && iframeid.Document.body.scrollHeight) {
                frameid.height = iframeid.Document.body.scrollHeight + 50;
            }
        }
    }
}

xxx.md

<script type="text/javascript" src="../js/my.js"></script>
<iframe width="100%" id="iframe_id" name="iframe_id" onload="Javascript:SetCwinHeight(this.id)" scrolling="auto" height="0" frameborder="0" src="https://www.abc.com/tools/a/">
</iframe>

特别说明:
在这里我说一下为什么要分开写,因为我发现不分开写没法正常加载js😂。

像下面这种:
`html


`

合起来写然后插入到 Markdown 里面貌似 hexo 渲染后 js 总有问题,不知是不是主题原因,我看过有一个 Next 主题的加载正常,蒙逼。。

出现的问题如下图:
cross-domain-erro

相信大家都看出来了,js代码乱掉了😂.

我自己也找过一些资料,其中不乏试过https://www.v2ex.com/t/162951#r_1717560说的使用Raw标签插件,但是没有用。。。

如果有人知道是什么原因的话,请告诉我一声谢谢!(在下方评论即可,PM我也可以)