首要要做配置操作,配置两个域名,我这里使用的是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> 中内容的额外限制。 可以在这里做调试 |
scrolling | yes no auto |
规定是否在 iframe 中显示滚动条。 |
seamless | seamless |
规定 <iframe> 看上去像是包含文档的一部分。 可以在这里做调试 |
src | URL | 规定在 iframe 中显示的文档的 URL。 |
srcdoc | HTML_code |
规定在 <iframe> 中显示的页面的 HTML 内容。 可以在这里做调试 |
width | pixels % |
定义 iframe 的宽度。 |
1、iframe无刷新文件上传
这个上传我服务器端使用的是PHP代码。
1 <div style="padding:20px"> 2 <h1>1、无刷新上传</h1> 3 <form action="action.php" enctype="multipart/form-data" method="post" target="iframeUpload"> 4 <iframe name="iframeUpload" width="400" height="400" frameborder='1'></iframe><br/> 5 <input id="file1" name="file1" type="file"> 6 <input value="上传图片" type="submit"> 7 </form> 8 </div>
使用iframe上传的关键点是target="iframeUpload",这个属性的设置。action.php中的代码如下:
1 <?php 2 require_once('upload.php'); 3 header("Content-Type:text/html;charset=utf-8"); 4 $type = array('jpg', 'jpeg', 'png', 'gif'); 5 $path = sprintf('%s/%s/%s/', date('Y'), date('m'), date('d')); 6 7 $upload = new App_Util_Upload('file1', 0, $type); 8 //获取上传信息 9 $info = $upload->getUploadFileInfo(); 10 $fileName = time() . rand(1000, 9999) . '.' . $info['suffix']; 11 $fullName = $path . $fileName; 12 $path = rtrim('upload', DIRECTORY_SEPARATOR) . '/' . $fullName; 13 $success = $upload->save($path); 14 $msg = $success ? '上传成功<br/>' : '上传失败<br/>'; 15 echo $msg; 16 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>
后面发现,如果在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",但事实与我的猜想完全不同
网络中的方法二:这个函数出自于前端开发博客。与上面的简单方法不同,这里多了些浏览器兼容方面的检验。
1 <script type="text/javascript"> 2 function setIframeHeight(iframe) { 3 if (iframe) { 4 var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow; 5 if (iframeWin.document.body) { 6 iframe.height = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight; 7 } 8 } 9 }; 10 window.onload = function () { 11 setIframeHeight(document.getElementById('iFrame2')); 12 }; 13 </script> 14 <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在线画的。
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中代码:
1 <body> 2 <img src="koala.jpg" /> 3 跨域访问! 4 <iframe id="iframeC" name="iframeC" width="0" height="0" style="display:none;" ></iframe> 5 <script type="text/javascript"> 6 function sethash(){ 7 hashH = document.documentElement.scrollHeight; 8 urlC = "http://www.iframe1.cn/agent.html"; 9 document.getElementById("iframeC").src=urlC+"#"+hashH; 10 } 11 window.onload=sethash; 12 </script> 13 </body>
agent.html中代码:
1 <body> 2 <script type="text/javascript"> 3 function pseth() { 4 var iObj = parent.parent.document.getElementById('iFrame3'); 5 iObjH = parent.parent.frames["iFrame3"].frames["iframeC"].location.hash; 6 iObj.style.height = iObjH.split("#")[1]+"px"; 7 } 8 pseth(); 9 </script> 10 </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。
这是一种非常优雅的方式,但是是用url的方式在传递参数,大小被受到了限制,如果数据量大的话,是会有问题的。
index_cross.html中代码:
1 <script type="text/javascript"> 2 function showQueryString(prompt) { 3 document.getElementById('testCross1').innerHTML = '跨域'+prompt; 4 }; 5 </script> 6 <iframe id="iFrame4" name="iFrame4" src="http://www.iframe2.cn/cross_domain1.html"> 7 </iframe> 8 <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中代码:
1 <body> 2 <script type="text/javascript"> 3 function getQueryString(name) { 4 var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); 5 var r = window.location.search.substr(1).match(reg); 6 if (r != null) return unescape(r[2]); return null; 7 } 8 parent.parent.showQueryString(getQueryString('cross')); 9 </script> 10 </body>
成功后出现的提示信息
网络方法二:
1) 支持HTML5的浏览器可以使用postMessage
IE8、IE9、firefox、chrome和safrai可用postMessage函数
index_cross.html中代码:
1 <script type="text/javascript"> 2 window.onload = function () { 3 if(window.postMessage) { 4 var ifr = document.getElementById('iFrame5'); 5 var targetOrigin = 'http://www.iframe2.cn/'; 6 //postMessage的第一个参数不仅仅可以是字符串,结构对象、数据对象(如:File和ArrayBuffer)或是数组都是可以 7 //但IE8/IE9/FireFox3.6及其以下版本只支持字符串数据 8 ifr.contentWindow.postMessage('I am parent!', targetOrigin); 9 } 10 }; 11 </script>
post_message.html中代码:
1 <body> 2 <div id="postmessage"></div> 3 <script type="text/javascript"> 4 window.onmessage = function(event){ 5 var event = event || window.event; 6 if (event.origin == 'http://www.iframe1.cn') { 7 document.getElementById('postmessage').innerHTML = event.data; 8 } 9 } 10 </script> 11 </body>
2) IE6、IE7可以用navigator对象的跨大域漏洞
index_cross.html中代码:
1 <iframe id="iFrame6" name="iFrame6" src="http://www.iframe2.cn/navigator.html" width="100%" height="100"></iframe> 2 <div id="testCross2"></div> 3 <script type="text/javascript"> 4 window.onload = function () { 5 navigator.a = function(prompt) { 6 document.getElementById('testCross2').innerHTML = '这是父页面的方法:'+prompt; 7 }; 8 var iframe = document.getElementById('iFrame6'); 9 if(typeof navigator.b === 'function') { 10 navigator.b('children'); 11 } 12 }; 13 </script>
navigator.html中代码:
1 <body> 2 <div id="navigator"></div> 3 <script type="text/javascript"> 4 navigator.b = function(prompt) { 5 document.getElementById('navigator').innerHTML = '这是子页面的方法:'+prompt; 6 } 7 setInterval(function(){ 8 if(typeof navigator.a === 'function') { 9 navigator.a('parent'); 10 } 11 }, 3000); 12 </script> 13 </body>