再谈Iframe的问题

iframe是可以做的事情非常多,比如通过iframe实现跨域,使用iframe解决IE6下select遮挡不住的问题,通过iframe解决Ajax的前进后退问题,再比如通过iframe实现异步上传。在很早我就写过一篇文章说明了Iframe在IE、firefox下的一些DOM操作。今天结合最近项目中遇见的iframe问题,再来谈谈iframe的一些常见问题解决方案。

IE下iframe背景透明问题

在firefox下,iframe背景默认的是透明的,在IE下默认不是透明的,我们可以使用allowTransparency='true'来设置IE下的iframe为透明,另外我们使用scrolling ='no' ``frameborder='0'分别来实现iframe页面没有滚动条,边框宽度。

IE6下iframe不显示的问题

不得不说IE6是个操蛋的浏览器,尤其是在中国!iframe有的时候在IE6中会出现不显示的问题,主要有以下几种原因,请一一排查:

  1. 可能你的iframe没有设置宽高,例如在table不居中,计算不出来td的高度,会导致这种问题
  2. 尝试使用下面的代码来重新载入IE6下的iframe页面:

    ```javascript

setTimeout(function(){
document.frames[‘fuckIE6’].location.reload();
},0)
```

  1. 传闻iframe标签中不要把src紧跟在iframe之后,也就是<iframe src='js8.in' name='fuckIE6'></iframe>是错误的,不过我没有碰见过类似的问题,为了保险起见,还是不要写成上面的样式为妙。

通过JSONP实现完美跨域

以前我经常在博客说JSONP,例如我的WordPress天气插件就是通过JSONP来调用的天气数据,今天就说说通过JSONP实现跨域的应用~

什么是JSONP

JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,我们可以通过使用 html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。这种跨域的通讯方式称为JSONP。

对于上面的解释,我们可以简单这样理解:JSONP就是可以通过JavaScript文件进行跨域通讯的方式,例如:现在各大网站风靡的搜索提示,搜狗云输入法
注意:JSONP服务器端代码需要充分做好安全措施。

使用hash来实现Ajax前进后退

Ajax应用中容易导致浏览器的前进后退按钮失效,不产生前进后退功能,在本文中断桥残雪就通过改变location.hash值来解决Ajax过程中导致的浏览器前进后退按键失效的问题,此方法兼容IE6+,Firefox,chrome,Safari,Opera等浏览器。

在去年断桥残雪已经写了一篇使用iframe来解决Ajax前进后退的方法,也提到了通过改变hash的方法来解决这个问题,这也是比较方便的方法,而使用iframe实现Ajax前进后退可以在不改变浏览器地址栏地址的前提下通过iframe地址的变化来“欺骗”浏览器产生前进后退,hash的方法则是直接改变浏览器地址栏地址,从而使浏览器产生前进后退。

hash导致浏览器产生前进后退原理

浏览器URL的hash值,指的是URL地址之后的#hash部分,我们可以通过JavaScript的location对象的location.hash方法来获得或者改变,但是IE中,不能设置,好像是IE中只能通过连接来实现hash的改变,不过我们可以通过jQuery插件hashchange中的$.locationHash函数来解决这个问题。

比如一个页面的地址是:http://js8.in/#top,那么这个页面的location.hash="#top",如果要改变这个地址的hash,可以给location.hash赋值,如:location.hash="#home",在IE下可以使用hashchange函数中$.locationHash(hash)给hash赋值。在日常我们常见的使用hash应用中,hash值使用最多的方式是返回顶部” 功能。

用document.domain+iframe实现Ajax跨子域

Ajax跨域一直是个比较麻烦的问题,例如:断桥残雪在一个项目中使用了open打开一个跟父窗口不同域名的新页面,结果子窗口就不能传值给父窗口了;再如:我在www.2fool.cn下不可以获取love.2fool.cn域名下的页面内容。浏览器的跨域限制是为了安全,可是当我们想要在一个域名下请求另外一个域名的内容的时候就感觉不那么爽了。

我在WordPress天气插件滔滔API接口处理上都使用了JSONP的方法来实现的跨域。而今天我要通过使用JS的document.domain和iframe来解决Ajax跨子域的问题

原理

通过给主页面跟请求页面设置相同的document.domain来,欺骗浏览器,达到Ajax跨子域的效果,此方法在IE,chrome,Firefox,Safari,Opera下测试通过。

缺点:无法实现不同主域名之间的通讯。并且当在一个页面中还包含有其它的iframe时,会产生安全性异常,拒绝访问。