iframe的一些记录

本文涉及的产品
.cn 域名,1个 12个月
简介: 首要要做配置操作,配置两个域名,我这里使用的是Apache。附件中的demo1和demo2

首要要做配置操作,配置两个域名,我这里使用的是Apache。附件中的demo1和demo2


<VirtualHost *:80>
    DocumentRoot "D:/htdocs/iframe/demo1"
    ServerName www.iframe1.cn
</VirtualHost>
<VirtualHost *:80>
    DocumentRoot "D:/htdocs/iframe/demo2"
    ServerName www.iframe2.cn
</VirtualHost>


iframe的一些属性介绍:

属性 描述
align left
right
top
middle
bottom
不赞成使用。请使用样式代替。
规定如何根据周围的元素来对齐此框架。
frameborder 1
0
规定是否显示框架周围的边框。
height pixels
%
规定 iframe 的高度。
longdesc URL 规定一个页面,该页面包含了有关 iframe 的较长描述。
marginheight pixels 定义 iframe 的顶部和底部的边距
marginwidth pixels 定义 iframe 的左侧和右侧的边距。
name frame_name 规定 iframe 的名称
sandbox ""
allow-forms
allow-same-origin
allow-scripts
allow-top-navigation

启用一系列对 <iframe> 中内容的额外限制。

可以在这里做调试

image.png

scrolling yes
no
auto
规定是否在 iframe 中显示滚动条。



seamless seamless

规定 <iframe> 看上去像是包含文档的一部分。

可以在这里做调试

image.png

src URL 规定在 iframe 中显示的文档的 URL。
srcdoc HTML_code

规定在 <iframe> 中显示的页面的 HTML 内容。

可以在这里做调试

image.png

width pixels
%
定义 iframe 的宽度。


1、iframe无刷新文件上传

这个上传我服务器端使用的是PHP代码。

image.pngimage.png


<div style="padding:20px">
        <h1>1、无刷新上传</h1>
        <form action="action.php" enctype="multipart/form-data" method="post" target="iframeUpload">
            <iframe name="iframeUpload" width="400" height="400" frameborder='1'></iframe><br/>
            <input id="file1" name="file1" type="file">
            <input value="上传图片" type="submit">
        </form>
</div>


使用iframe上传的关键点是target="iframeUpload",这个属性的设置。action.php中的代码如下:


<?php
require_once('upload.php');
header("Content-Type:text/html;charset=utf-8");
$type = array('jpg', 'jpeg', 'png', 'gif');
$path = sprintf('%s/%s/%s/', date('Y'), date('m'), date('d'));
$upload = new App_Util_Upload('file1', 0, $type);
//获取上传信息
$info = $upload->getUploadFileInfo();
$fileName = time() . rand(1000, 9999) . '.' . $info['suffix'];
$fullName = $path . $fileName;
$path = rtrim('upload', DIRECTORY_SEPARATOR) . '/' . $fullName;
$success = $upload->save($path);
$msg = $success ? '上传成功<br/>' : '上传失败<br/>';
echo $msg;
echo '<img src="'.$path.'" width="300" height="300"/>';


2、iframe自适应高度


同域的情况下:

网络中的方法一:直接用onload函数获取iframe中的内容高度,如果页面载入一次以后,高度不变,这招是挺好用的,但是我在firefox与IE中,表现不理想,如图,并没有完全的将页面显示,chrome和safrai的表现不错。


<iframe id="iFrame1" name="iFrame1" width="100%" onload="this.height=iFrame1.document.body.scrollHeight" 
frameborder="0" src="autoheight.html" scrolling="no"></iframe>


image.png


后面发现,如果在iFrame1.document.body.scrollHeight的后面在加上20的话,iframe也是能完全展现出来的,这个应该是受到了我autoheight.html这个页面里的CSS影响,

autoheight.html中的页面代码是这样的:

 


1 <div style="padding:20px;border:1px solid #000;width:650px">
2         <img src="autoheight.jpg" width="600"><br/>
3         一张图片
4 </div>


为了验证我的猜想,我把padding给去除掉,还是用原先的代码onload="this.height=iFrame1.document.body.scrollHeight",但事实与我的猜想完全不同

image.png


网络中的方法二:这个函数出自于前端开发博客。与上面的简单方法不同,这里多了些浏览器兼容方面的检验。


<script type="text/javascript">
            function setIframeHeight(iframe) {
                if (iframe) {
                    var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;
                    if (iframeWin.document.body) {
                        iframe.height = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight;
                    }
                }
            };
            window.onload = function () {
                setIframeHeight(document.getElementById('iFrame2'));
            };
 </script>
 <iframe id="iFrame2" name="iFrame2" width="100%" frameborder="0" src="autoheight.html" scrolling="no" onload="setIframeHeight(this)"></iframe>


var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;

这句是用来获取iframe的window对象。

文章Iframes, onload, and document.domain中 说“he iframe element object has a property called contentDocument that contains the iframe’s document object, so you can use the parentWindow property to retrieve the window object.”

意思就是一些浏览器可以通过iframeElement.contentDocument.parentWindow获得iframe的window对象。经过测试发只有IE9与IE8是根据iframe.contentDocument.parentWindow来获取的,其他firefox、chrome、safrai、IE6、IE7都是根据frame.contentWindow获取的


iframe.height = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight;

这句话就是在获取iframe的高度了。

body是DOM对象里的body子节点,即 <body> 标签;

documentElement 是整个节点树的根节点root,即<html> 标签;

刚刚上一个方法由于用的是body.scrollHeight导致了各个浏览器的解释不同,引起了显示的不一致。经测试发现使用documentElement.scrollHeight后,都能正确显示。

 

异域的情况下:


跨域的时候,由于js的同源策略,父页面内的js不能获取到iframe页面的高度。需要一个页面来做代理。总共有三张页面,


注意下三个页面的域名

http://www.iframe1.cn/index.html

http://www.iframe1.cn/agent.html

http://www.iframe2.cn/iframe.html

index.html与agent.html在同一个域名下

iFrame3与iframeC分别为index.html与iframe.html页面上面的iframe的id。下面的图是用websequencediagrams在线画的。

image.png


index.html中代码:


<iframe id="iFrame3"  name="iFrame3" src="http://www.iframe2.cn/iframe.html" width="100%" height="0" scrolling="no" frameborder="0"></iframe>


iframe.html中代码:


<body>
    <img src="koala.jpg" />
    跨域访问!
    <iframe id="iframeC" name="iframeC" width="0" height="0" style="display:none;" ></iframe>
    <script type="text/javascript">
    function sethash(){
        hashH = document.documentElement.scrollHeight;
        urlC = "http://www.iframe1.cn/agent.html";
        document.getElementById("iframeC").src=urlC+"#"+hashH;
    }
    window.onload=sethash;
    </script>
</body>

agent.html中代码:


<body>
    <script type="text/javascript">
    function  pseth() {
        var iObj = parent.parent.document.getElementById('iFrame3');
        iObjH = parent.parent.frames["iFrame3"].frames["iframeC"].location.hash;
        iObj.style.height = iObjH.split("#")[1]+"px";
    }
    pseth();
    </script>
</body>


3、iframe跨域通信


网络方法一:这是一种通过第三张页面来跨域执行函数,一种代理的感觉


注意下三个页面的域名

http://www.iframe1.cn/index_cross.html

http://www.iframe1.cn/cross_domain2.html

http://www.iframe2.cn/cross_domain1.html

index.html与cross_domain2.html在同一个域名下


iFrame4与iframeD分别为index_cross.html与cross_domain1.html页面上面的iframe的id。

image.png


这是一种非常优雅的方式,但是是用url的方式在传递参数,大小被受到了限制,如果数据量大的话,是会有问题的。

index_cross.html中代码:


<script type="text/javascript">
            function showQueryString(prompt) {
                document.getElementById('testCross1').innerHTML = '跨域'+prompt;
            };
</script>
<iframe id="iFrame4"  name="iFrame4" src="http://www.iframe2.cn/cross_domain1.html">
</iframe>
<div id="testCross1"></div>

cross_domain1.html中代码:

<body>
    <iframe id="iframeD" name="iframeD" src="http://www.iframe1.cn/cross_domain2.html?cross=success"></iframe>
</body>

cross_domain2.html中代码:


<body>
    <script type="text/javascript">
        function getQueryString(name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
            var r = window.location.search.substr(1).match(reg);
            if (r != null) return unescape(r[2]); return null;
        }
        parent.parent.showQueryString(getQueryString('cross'));
    </script>
</body>



image.png

成功后出现的提示信息

网络方法二:

1) 支持HTML5的浏览器可以使用postMessage

  IE8、IE9、firefox、chrome和safrai可用postMessage函数

  index_cross.html中代码:


<script type="text/javascript">
            window.onload = function () {
                if(window.postMessage) {
                    var ifr = document.getElementById('iFrame5');
                    var targetOrigin = 'http://www.iframe2.cn/';
                    //postMessage的第一个参数不仅仅可以是字符串,结构对象、数据对象(如:File和ArrayBuffer)或是数组都是可以
                    //但IE8/IE9/FireFox3.6及其以下版本只支持字符串数据
                    ifr.contentWindow.postMessage('I am parent!', targetOrigin);
                }
            };
</script>


 post_message.html中代码:


<body>
    <div id="postmessage"></div>
    <script type="text/javascript">
        window.onmessage = function(event){
            var event = event || window.event;
            if (event.origin == 'http://www.iframe1.cn') {
                document.getElementById('postmessage').innerHTML = event.data;
            }
        }
    </script>
</body>


image.png

 


2) IE6、IE7可以用navigator对象的跨大域漏洞

  index_cross.html中代码:


<iframe id="iFrame6"  name="iFrame6" src="http://www.iframe2.cn/navigator.html" width="100%" height="100"></iframe>
        <div id="testCross2"></div>
        <script type="text/javascript">
            window.onload = function () {
                navigator.a = function(prompt) {
                    document.getElementById('testCross2').innerHTML = '这是父页面的方法:'+prompt;
                };
                var iframe = document.getElementById('iFrame6');
                if(typeof navigator.b === 'function') {
                    navigator.b('children');
                }
            };
</script>

  navigator.html中代码:

<body>
    <div id="navigator"></div>
    <script type="text/javascript">
        navigator.b = function(prompt) {
            document.getElementById('navigator').innerHTML = '这是子页面的方法:'+prompt;
        }
        setInterval(function(){
            if(typeof navigator.a === 'function') {
                navigator.a('parent');
            }
        }, 3000);
    </script>
</body>


image.png


 

源码可以在这里下载:

iframe.rar


相关文章
|
4月前
|
JavaScript 前端开发 API
快速实现 iframe 嵌套页面
【6月更文挑战第22天】快速实现 iframe 嵌套页面
|
3月前
|
前端开发 JavaScript 应用服务中间件
iframe动态操作标签分享
iframe动态操作标签分享
28 0
多Iframe版后台,在一个iframe切换到另一个iframe,同时刷新
多Iframe版后台,在一个iframe切换到另一个iframe,同时刷新
200 0
多Iframe版后台,在一个iframe切换到另一个iframe,同时刷新
|
Web App开发 前端开发 容器
如何解决 iframe 无法触发 clickOutside
在公司的一次小组分享会上,组长给我们分享了一个他在项目中遇到的一个问题。在一个嵌入 iframe 的系统中,当我们点击按钮展开 Dropdown 展开后,再去点击 iframe 发现无法触发 Dropdown 的 clickOutside 事件,导致 Dropdown 无法关闭。
2907 0
|
Web App开发 JavaScript 前端开发