不同浏览器处理后退的一些异同

以前在测试自己写的webim时发现firefox有一个很人性化的特性:在页面上跟别人聊天的时候如果不小心点到了本页打开的链接,只要点一下 Firefox的后退按钮,就会退后到之前的页面,可以接着聊。也就是说在firefox中点击后退,原来页面的状态会还原,包括JS改变的DOM结构也 会保持。

我们用下面的代码来测试一些常见的浏览器是怎么处理后退的。测试的浏览器有IE8beta2、Firefox3.0.1、Flock1.2.4(Firefox2.0.0.16内核)、Safari3.1(window版)、Opera9.60。

< a href = " http://www.baidu.com " > 百度 </ a >
< div id = " a1 " ></ div >
< script type = " text/javascript " >
  window.onload = function(){
    alert("load");
    var i = 1;
    setInterval(function(){
      document.getElementById("a1").innerHTML = i++;
    },500);
  };
</ script >

测试结果:IE8点后退时会触发之前页面的window.onload事件,计数器回到初始状态重新计数;Opera9.6后退时不会触发前一个页 面的window.onload事件,但定时器停止运行;其它浏览器后退时都不会触发前一个页面的window.onload事件,定时器会接着之前的状 态继续计数。

结论:Firefox、Opera、Safari在这方面都做得比较人性化,完全的保留了页面unload时的状态,估计是直接从内存中读取缓存数 据,所以后退速度相当快;其中Opera9.6会导致计数器停止,可能是个bug。IE在后退时则会回到最初状态,之前JS改变的DOM不复存在。

如果想让非IE浏览器退后时也能触发window.onload事件呢?这篇文章提到了解决方案。其实就是在页面是加入:

window . onunload = function (){} ;

经测试,此方法可行。对于其中的原理,JK给出了如下解释:

FF/Safari等会努力做得很理想(完完全全的保持上次的unload时的信息),不过,如果他认为用户的代码(典型的是在onunload里)会破坏他的理想计划时,他就退一步,把“后退”当作“后退+reload”。

 

上次一位网友在我blog留言问到如何修正Ajax后退失效,这是在开发Ajax应用时很常见的需求。这篇文章就简单的介绍一下怎么解决这个问题。

首先我们要清楚后退按钮会失效的原因:使用Ajax时,页面通过XMLHttpRequest来更新内容,并没有Redirect,所以浏览器不会出现前进后退。这也是Ajax刚出来时遭到很多人批判的一个原因,其中细节可以参考这两篇文章《Ajax: 99% Bad》、《AJAX的七宗罪》。这个问题其实跟Ajax无关,不过Ajax的出现使得一个页面实现无刷新更新更容易,这个时候人们开始意识到,一个页面发生巨大改变而不能后退是一件很痛苦的事情。

要解决这个问题,就要控制浏览器的history,在页面发生改变时往浏览器历史里插入一条记录。但是出于安全的目的,JS是不能直接操作 history的。我们必须采用其他方法:IE中,在页面中插入一个隐藏的iframe,通过改变iframe的location或者DOM,都可以在主 窗口的history中产生新记录,详细研究可以参考这篇文章;在其他浏览器(Firefox、Opera、Safari)中没有这么复杂,只需改变url就可以产生一条新的history记录,当然url不能乱改,要不页面就跳转走了,通常我们改变的是location.hash,也就是url“#”以后的部分。下面是具体实现:

首先在页面中放一个隐藏的iframe:

< style type = " text/css " title = " default " media = " screen " >
#history_iframe{position:absolute;top:0; left:0;width:1px; height:1px;visibility:hidden}
</ style >
< iframe id = " history_iframe " src = " blank.html " ></ iframe >

blank.html的内容也很简单,放了一个div来存当前的hash:

< html >
 
< head >< title > hack iframe </ title ></ head >
 
< body >< div id = " state " ></ div ></ body >
</ html >

对不同浏览器采用不同方法控制history:

var isIE = typeof ( window . opera ) != " object " && window . navigator . userAgent . indexOf ( " MSIE " ) > 0 ;
var $ = function ( s ){ return document . getElementById ( s )} ;
function update_status ( str ){
 
if ( isIE ){
    
try {
      
var doc = $ ( " history_iframe " ) . contentWindow . document ;
      
doc . open () ;
      
doc . write ( ' <html><body><div id="state"> ' + str + ' </div></body></html> ' ) ;
      
doc . close () ;
    
} catch ( e ){}
 
}
 
location . hash = str ;
} ;

可以测试一下了:

< button onclick = " update_status('test1') " > test1 </ button >
< button onclick = " update_status('test2') " > test2 </ button >
< button onclick = " update_status('test3') " > test3 </ button >

上面就是控制浏览器history的基本原理,通过点击三个按钮,会往浏览器写入三条历史记录,这样尽管页面依旧没有刷新,但是浏览器的前进后退却 能开始工作了。剩下的工作很简单:利用一个定时器不停的检测状态是否发生变化(IE检测iframe里state的innerText;其他浏览器检测 location.hash),然后在检测到状态改变时调用相应的方法还原页面内容。限于篇幅,这一部分代码就不贴出来了。完整的实例在这里

见:http://www.qgy18.com/2008/09/howto_control_browser_history/
 

 

 

在Ajax编程时,经常需要从服务端获取数据。通过情况下,我们是直接把要传输的数据放在response正文中,再用responseText或者responseXML来得到内容。最近偶然发现,有时候也可以把数据放在header里,而且一些情况下这样做更有优势。

header是服务器以HTTP协议传送HTML资料到浏览器前所送出的字符串,在php中我们可以这么发送自定义header:

header ( " author:Jerry Qu " ) ;

然后在客户端,正常的创建一个Ajax请求,所不同的地方是callback中获取数据改成:

var a = new Ajax () ;
a . get ( " test.php " , function (){
    
alert ( a . req . getResponseHeader ( " author " )) ;
}) ;

这样就能取到author的值了。

Javascript中跟response header有关的就两个方法:

getResponseHeader
从响应信息中获取指定的http头
语法
strValue = oXMLHttpRequest.getResponseHeader(bstrHeader);

getAllResponseHeaders
获取响应的所有http头
语法
strValue = oXMLHttpRequest.getAllResponseHeaders();

通过header可以传多少数据呢?我测试了一下,在firefox中如果超过10232个英文字符,客户端就取不到数据了,IE中测试了100W 个字符依然可以,所以基本还是够用的。另外,我也测试过一次发送1000个自定义header,IE和FF中都能正常取到值。如果你想得到http header的更多信息,建议阅读这篇文档

这样做的优点呢?通常如果用Ajax来post数据,服务端返回json格式字符串的情况下,在浏览器中输入request的地址,用户就会看到那 堆奇怪的代码。在页面丢失js时这种现象很常见。但是把返回数据放在header里就不会有这个问题,反正header不会展示出来。正文里可以随意的放 些什么内容,哪怕是放一段自动转向JS也没关系,这样用户体验要稍好一些。

查看本文实例

另见:http://www.w3help.org/zh-cn/causes/BX2004

转载于:https://www.cnblogs.com/antony1029/archive/2011/01/10/1932209.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值