解惑

解己之惑,解人之惑

分类:AJAX

AJAX

jQuery成为新的AJAX基础库标杆

技术的发展真的是日新月异,AJAX开始风生水起的时候,prototype是AJAX基础库的标准,很多AJAX库都是基于它的,而现在,jQuery很可能会或者已经取代prototype成为AJAX基础库了。不知道是我太后知后觉还是技术发展实在太快,短短几个月的时间,我已经又不熟悉最新的AJAX动态了。
Ruby语言的特性(以$为标志)向JavaScript转移的风气愈演愈烈,本来我是对这种风格不太认同的,但是感觉必须接受了,在简单和可读性之间,我们是得做一些牺牲了,毕竟一个东西变成大家都熟悉并引以为标准后,它的可读性无形上就提高了很多,因为你读不懂,只能说明你落后了,或者变成新“文盲”了。

JSR168

JSR168规范是定义portlet容器及portlet之间的关系的,但是由于定稿比较早(2003年10月),所以没有涉及到portlet的独自渲染和刷新,而这个是现在的web2.0或者新一代web界面所不可或缺的,当然,新的JSR286规范可能会解决这个问题,但是我们不能等待这个规范的出台。就目前的情况看,融合jsr168和AJAX并不会很困难,问题的关键是没有一个轻量的组件或者成熟的解决方案,有的只是大的软件厂商在他们的portal产品中提供这种特性的支持。这段时间一直在用pluto,刚刚整合到我们的系统中,看了下pluto最终渲染出来的页面片断:
  <!– Assemble the rendering result –><br />
 
<div id="/testsuite.TestPortlet!764587357|0" class="portlet"><br />
  
<div class="header"><br />
      <!– Portlet Mode Controls –><br />
      <a href="http://localhost:8080/pluto/portal/__pm0x3testsuite0x2TestPortlet1!764587357|0_view"><span class="view"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__pm0x3testsuite0x2TestPortlet1!764587357|0_edit"><span class="edit"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__pm0x3testsuite0x2TestPortlet1!764587357|0_help"><span class="help"></span></a><br />
      <!– Window State Controls –><br />
      <a href="http://localhost:8080/pluto/portal/__ws0x3testsuite0x2TestPortlet1!764587357|0_minimized"><span class="min"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__ws0x3testsuite0x2TestPortlet1!764587357|0_maximized"><span class="max"></span></a><br />
      <a href="http://localhost:8080/pluto/portal/__ws0x3testsuite0x2TestPortlet1!764587357|0_normal"><span class="norm"></span></a><br />
      <!– Portlet Title –><br />
    
<h2 class="title">Test Portlet #1</h2>
<br />
    </div>
<br />
  
<div class="body"><br />
从这个输出来看,我们需要做的可能很简单,替换portlet-skin.jsp,重新定义那些按钮的输出为一个javascript,这样应该就可以部分刷新了。目前我们产品的其它一个功能已经可以做到这个了。现在的问题就是转换了。

浏览器缓存

相信有不少人会遇到浏览器缓存的问题,因为IE默认会缓存访问过的网页,特别是URL的参数是固定的,但是很可能内容会变化。
大部分都知道的可能是在head中增加meta信息:
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
而有文章指出这个依然有问题,如果网页内容超过32K,那么那个设置就实效了,所以要把它放到网页的最后:
            <BODY>
网页内容。。。
</BODY>
<HEAD>
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
</HEAD>
</HTML>

现在AJAX很流行,而AJAX返回的内容很可能不再是一个完整的网页,那么就不能使用上述的方法,有另外的文章说到可以使用服务器端的HTTP头控制,我试验的结果是无效
    response.setHeader("Cache-Control","no-cache");
    response.setHeader("Cache-Control","no-store");
    response.setHeader("Cache-Control","must-revalidate");

最后采取的方法就是在使用AJAX发送请求的时候附加一个时间戳:
var xmlhttp = createrequest();
xmlhttp.open("GET",appendTimestamp(url),true);

  function appendTimestamp(url)
  {
      if (url.indexOf("?")>0)
      {
          return url+"&ajax_time="+new Date().getTime();
      } else
      {
          return url+"?ajax_time="+new Date().getTime();
      }
  }

当然这个方法也只能解决部分问题,如果URL太长也不行。

更新:
对于AJAX的情况,也可以使用
xmlhttp.setRequestHeader("Cache-Control","no-cache");

推荐另外一个日志:再论怎么有效利用浏览器缓存之怎么避免浏览器缓存静态文件

2007年2月28日更新:
使用服务器端控制AJAX页面缓存:
    response.setHeader( "Pragma", "no-cache" );
    response.addHeader( "Cache-Control", "must-revalidate" );
    response.addHeader( "Cache-Control", "no-cache" );
    response.addHeader( "Cache-Control", "no-store" );
    response.setDateHeader("Expires", 0);
单纯的使用 xmlhttp.setRequestHeader("Cache-Control","no-cache")无效。

关于AJAX的一些思考

公司的产品中也引入了AJAX,但是是很简单的,代码都是自己写的,开发经理Paul看到Yahoo的新邮箱后感觉不错,期望我们也使用AJAX(实际上我们已经在使用了)。
使用AJAX,个人感觉有一些问题,首先就是开发难度,JavaScript的调试比较困难(相对于Java),而且还要解决浏览器兼容问题,另外一个就是性能,如果使用不好,对于性能反到是有害的,很多站点的解决方案都是一个大框架页面,剩下的块块都是使用AJAX一个一个加载(我们也是),这个对服务器端的负载实际是加重了。
当然也并非没有办法解决,首先就是要有一个合适的AJAX的框架,开发人员需要考虑的问题相对较少;其次就是和服务器端的交互,可以使用某种客户端缓存机制减轻负载并加快用户操作的相应时间。如果页面一直保持不完全刷新,那么这样的AJAX方案还是可以接受的,最怕的就是要经常完全刷新页面,或者是internet应用,需要对搜索引擎友好。

推荐一个AJAX相关的JS库:setInnerHTML

>跨浏览器的设置innerHTML方法

这个JS库是无意中发现的,而且刚好我们的产品要引入AJAX,但是我们又不能使用纯粹的AJAX方案,因为我们的产品已经开发了很长时间了,服务器端返回的是HTML,要专门为引入的AJAX返回特殊的内容工作量比较大,但是由于返回的HTML比较复杂,还可能包含了JS文件的引用以及JS代码,所以在IE下或者FF下总是有这样那样的问题,这个JS库的引入很好的解决了我们面临的问题,推荐在已有B/S产品或者项目中引入AJAX特性的项目使用这个解决方案。

IE的并发连接请求限制导致的问题

公司的产品导入了AJAX,但是后来发现一个严重的问题,就是在IE下,首页切换到其它页面比较困难,特别是首页还有一个下拉列表,选择不同的值会将首页的那些AJAX区域重新加载,如果其中几个比较慢(服务器端返回比较慢,因为有些存在性能问题,数据量大了以后查询特别慢),那么切换的时候要等很长时间,所以表面上看上去就是IE死掉了,但是在FireFox下没有这个问题。后来查证是IE下有两个并发连接请求的限制,每个AJAX请求也都算一个请求。后来的解决办法就是将AJAX请求排队,一个执行完了才能执行另外一个,这样无论怎么切换都是马上响应的,这个修改只对IE有效,FF下就不进行限制。
阅读全文

© 2024 解惑

本主题由Anders Noren提供向上 ↑