Ajax使用总结

.概述

使用Ajax有两个月的时间了,从简单应用到复杂应用都做了一些,分别应用到了系统的两个模块中,趁着空闲时间,对Ajax使用中的问题和解决进行一下总结。

本文不对任何Ajax框架进行讨论,仅仅针对一些使用技巧和基本问题解决进行分析。同样不对Ajax技术进行讨论,因为对Ajax的技术介绍可以在网上搜索到一堆。

.常见问题

1.缓存问题

出现这个问题主要是因为发起Http请求的时候,IE包办了Cache策略,很多时候明明更新了数据,但却无法获得更新后的数据。

网上有一些解决此问题的方法,比如在URL后边加随机数,但这仍然不是一个好的解决办法。

比较好的解决方法是:前台在提交数据以后,需要强制更新数据的时候,给XMLHttp对象加入:

xmlhttp.setRequestHeader("If-Modified-Since", "0");

2.中文问题

老生常谈的问题了,在Ajax中的中文问题,一般来说表现为两个方面:1.发送异步请求时参数的中文问题;2.请求响应数据的中文问题。

⑴参数中文问题

一般来说,参数的中文问题解决起来主要依赖于使用的环境,而且依赖于环境所使用的编码方式,而并不像网上的一些文章写的那样。

XMLHTTP对象Post表单的时候,是默认的用UTF-8字符来发送的。如果你的网页本来就是用的UTF-8编码的话,那么接收到的数据是正常的;如果你的网页编码是GB2312的话,问题就来了,POST过来的数据是UTF-8,而你整个站点是用GB2312来显示,那么所有的中文字符将全部变成乱码。

当使用Servlet接收请求参数时,最好先加入:

response.setContentType("text/xml");

response.setCharacterEncoding("GB2312");

当提交方式为POST时,一定要设置成UTF-8,否则会出现乱码:

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "utf-8");

当提交方式为GET时,则要设置成GB2312或者GBK,否则会出现乱码:

String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "GB2312");

当使用JSP接收请求参数时,需要先将请求接收页的编码方式修改为UTF-8,然后将中文请求参数进行两次encodeURI操作,如:encodeURI(encodeURI(form["name"].value))。最后使用下边的语句接收中文参数:

String name = java.net.URLDecoder.decode(request.getParameter("name"), "UTF-8");

另外,当使用Struts框架接收中文参数的时候,最好也使用上述双重encodeURI的方法。

(2)响应中文问题

responseText中的中文出现乱码,是因为xmlhttp在处理返回的responseText的时候,是把resposeBodyUTF-8编码进解码形成的,如果服务器送出的确实是UTF-8的数据流的时候汉字会正确显示,而送出了GBK编码流的时候就乱了。解决方法就是在送出的流里面加header,指明送出的是什么编码流,这样xmlhttp就正常了。

response.setHeader("Charset", "GB2312");

3.并发请求问题

使用Ajax的时候,通常有一些页面可能会同时发送多个异步请求,在这里我把它叫做并发的异步请求,其实这并不能算做一个问题,但很多时候,编码者为了节省代码书写量,而只构造一次XMLHttpRequest对象,到处使用的话,这个问题就会出现,因为前面的请求还未完成,后面的请求就会把前面的请求覆盖掉。

最简单的解决方法是为每个异步请求分配XMLHttpRequest对象,并分别实例化(JavaScript也是可以面向对象的),这样就可以保证每个请求都有自己独立的XMLHttpRequest对象来进行异步访问。

但是每次都创建一个新的XMLHttpRequest对象,也会造成浪费。最好的办法就是创建一个XMLHttpRequset的对象池,如果池中有空闲的对象,则使用此对象,否则将创建一个新的对象。XMLHttpRequest对象池JavaScript代码在附件中.

4.返回JavaScript问题

很多时候,响应的数据希望用JavaScript处理,比如把响应的数据用对话框的形式弹出,或者将返回数据构造成下一步请求的参数,都需要把响应的数据构造成JavaScript代码并在需要的时机调用执行。但是我们会发现,当使用响应数据构造新的JavaScript后,使用innerHTML方法放入DHTML层中的JavaScript是无法执行的。这是因为,JavaScript是在页面加载的同时进行解析的,也就是说innerHTML中的JavaScript代码是无法被解析的。

解决这个问题需要把JavaScript代码在层中重新解析,解析代码在附件中.

.注意

1.提示的必要性

    由于Ajax不同于原始的Web请求/响应方式,所以提示是非常必要的,可以说可视化的提示越多越好。如果我点击的这个东西触发了Ajax一个动作,那么程序必须给我一个可视化的提示,告诉我有些动作正在执行,比如loading…、数据加载等等。这样明显的向用户提示出程序的动作,从而克服Ajax不再重载页面而带来的用户不知操作是否进行的不便,不要让用户发出“这个该死的程序究竟在干什么”的牢骚。

2.请求超时的必要性

错误的操作或者执行可能是在所难免的,有的时候针对DOM的一些错误操作,Ajax是无法给出响应的。这样的话,我们参考第5点完美的给出了用户提示,如果接收不到响应的话,那么提示将一直持续下去。这时,请求超时就非常有必要了,我们可以通过在函数调用后设置一个timer(用Javascriptontimeout函数)来建立一个超时机制。如果没有返回的话,这个timer就可以明确地执行abort()(终止操作),并且通知用户。

.技巧

1.加速应用

Ajax操作时,为了方便程序的书写,我们可能需要引入很多css样式表或者类似JavaScript对象池和innerHTML解析等等JavaScript文件,或者prototype.js等工具性的JavaScript文件。这样可能打开某页面的时候,就需要下载很多的文件,这样就会造成加载页面的时候,需要有一个下载文件的过程。

优化的方案:

n         将多个JavaScript或者css文件整合成一个文件以减少HTTP连接数;

n         使用类似jsmin的工具移除注释、空白以及多余的空行等,以减少网络传输的数据量;

n         web服务端应用gzip compression 压缩。

关于HTTP Compression,则是优化Ajax最为关键的部分。我们可以应用Web Server默认提供的机制,比如Tomcat5.x Connector 配置中提供的压缩选项,一个典型的Connector配置如下:

port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25"

maxSpareThreads="75" enableLookups="false" redirectPort="8443"

acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"

compression="on" compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css"

/>

    以上配置使用compression属性激活压缩,然后用compressableMimeType属性设置应用压缩的Mime Type类型。最著名的Apache服务器也提供了mod_deflate 等模块提供类似的压缩配置。

2.使用JSon

很多人都在网上说,Ajax不如修改为Ajaj,也就是把XML弄“下岗”,然后由JSon作为响应数据回传给用户。由于JSon组织简单、访问方便,正被很多人接受,使用JSon可参考以下代码:

<script language="javascript" type="text/javascript">

var d = {

       "msg":[{

              "user":"dabao",

              "msg":"天才"

              },

              {

              "user":"dirk nowitzki",

              "msg":"dallas mavericks #41"

              }

       ],

       "type":"dirk nowitzki"

};

alert(d.type);

alert(d.msg[0].msg);

alert(d.msg.length);

for (var o in d) {

       alert(d[o]);

}

</script><script language="javascript" type="text/javascript">

var d = {

       "msg":[{

              "user":"dabao",

              "msg":"天才"

              },

              {

              "user":"dirk nowitzki",

              "msg":"dallas mavericks #41"

              }

       ],

       "type":"dirk nowitzki"

};

alert(d.type);

alert(d.msg[0].msg);

alert(d.msg.length);

for (var o in d) {

       alert(d[o]);

}

</script>

由于本人水平有限,文中一些问题解决是搜索得来,同时希望牛人高手们说出遇到的问题及解决方法:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值