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

mac2022-06-30  76

以前在测试自己写的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

最新回复(0)