ajax技术(JavaScript和XML的综合)
全称:Asynchronous(异步) JavaScript And XML (异步的JavaScript和XML)。
1. ajax是一种用来改善用户体验的技术,其实质是利用浏览器内置的一个特殊的对象(XMLHttpRequest一般称之为ajax对象),异步地(当ajax对象发请求时,浏览器不会销毁当前页面,用户任然可以对当前页面做其的操作)向服务器发送请求,服务器送回部分数据(不是完整的页面),利用这些数据更新当前页面。整个过程,页面无刷新,不打断用户的操作。
2. ajax对象是BOM模型里的,几乎所有的浏览器都有这个对象。
3. Ajax技术是若干技术的综合应用,主要涵盖JavaScript,XMLHttpRequest(发请求接收响应信息),XML,HTML,CSS.(这些技术融合在一起就是Ajax)。
ajax技术的优点
1. 页面无刷新,不打断用户的操作。
2. 浏览器与服务器之间可以按照需要获取数据,不需要再传送一个完整的页面。也就是说,浏览器与服务器之间数据传输量大大减少。(性能有所提高)
3. 是一种标准化的技术,不需要浏览器额外去下载一些插件。
作用:用于客户端和服务器端交互的一项技术.主要用于页面的局部刷新,不需要刷新整个页面,提升用户的体验度
原有交互主要基于提交表单,采用点超连接方式,这种方式主要有以下一些弊端:
a. 请求发出后,如果响应速度慢,客户需要等待,而且是茫然的等待
b. 请求响应回来需要刷新整个页面,如果页面中有需要频繁更新的数据,会造成整个页面的频繁刷新.(而实际:只有某个区域需要刷新,不需要整个页面刷新.)
采用Ajax技术之后,可以解决以上问题.提升用户的体验度
Ajax技术原理
Ajax技术使用时,需要编写客户端脚本和服务器端处理程序。原理如下:
1. 首先客户端利用JavaScript创建一个XMLHttpRequest对象
2. 利用XMLHttpRequest对象(ajax引擎),创建和发送一个请求
3. 请求到达服务器,调用Servlet组件处理,处理完毕后,返回响应数据,数据可以采用字符串或XML格式返回。
4. XMLHttpRequest接收到服务器返回的数据,调用客户端的回调函数,将数据更新到页面
如何获得XMLHttpRequest对象?
因为XMLHttpRequest没有标准化,要区分浏览器来获得这个对象:
function getXhr(){ var xhr=null; if(window.XMLHttpRequest){ //非IE浏览器 xhr = new XMLHttpRequest(); }else{ //IE浏览器 xhr = new ActiveXObject(‘Microsoft.XMLHttp’); } return xhr; }
XMLHttpRequest对象的使用
该对象是由浏览器提供的,在IE中该对象以ActiveXobject组件形式存在,在其他浏览器中以XMLHttpRequest形式存在。
XMLHttpRequest对象主要的函数和属性
open(param1,param2,param3)函数
创建一个请求,与服务器之间建立连接。
param1:用于指定请求类型,可以是"get","post"。get请求必须将请求参数添加到请求资源路径的后面。
param2:用于指定请求URL地址
param3:用于指定请求发出方式:true异步(默认的),false表示同步。
异步请求:发请求时,浏览器不会销毁当前页面,用户可以对当前页面做其他操作
同步请求:发请求时,浏览器不会销毁当前页面,浏览器会锁定当前页面,用户不能对当前页面做其他操作,只有请求处理完成返回时,用户才可以继续做其他操作。
同步:(请求1-响应1)(请求2-响应2)必须要在第一个请求得到响应后在能发第二次请求
同步模式:请求1-->响应1回调执行-->请求2
异步:(请求1,请求2,) (响应1,响应2,) 不需要第一个请求得到响应后再发第二次请求
异步模式:请求1-->请求2-->响应1回调执行
send(param1)函数
发送一个请求,把open的请求发出去。
param1:用于指定请求发送时提交的数据。如果是get请求,param1指定为null。如果是post请求,需要指定为"key=value&key=value"
onreadystatechange事件
用于指定注册的回调函数.指定函数名不需要()。该事件在readyState属性值发生改变时触发该事件。当ajax对象的readyState属性值发生了改变(比如从0变成了1),则会产生readystatechange事件。
readyState属性
readyState有5个值,分别是0,1,2,3,4,表示ajax对象与服务器进行通信时的状态。比如,值为4时表示ajax对象已经成功德获得了服务器返回的所有的数据。只有当readyState的值等于4时,才能使用responseText等属性获得服务器返回的数据。
0 请求未初始化(对象已建立,但是尚未初始化) open函数未调用
1 请求已初始化 open调用,send未调用
2 请求已发送 send方法已调用
3 请求正在处理中
4 请求处理完毕
状态会自动改变。每次状态改变时都会触发onreadystatechange事件.即会调用一次回调函数
status属性
用于获取请求处理的状态码。例如:404 500 200等 404:找不到处理资源 500:找到资源,执行出错 200:执行成功
responseText属性
用于获取服务器处理返回的字符串信息。需要在readyState==4&&status==200执行,才可以获取正常数据
responseXML属性
用于获取服务器处理返回的XML结果对象。很少使用,因为解析XML文件比较慢,XML文件也比较大。
Ajax程序的编写步骤
step1、获得XMLHttpRequest对象,var xhr=getXhr();
step2、发送请求(get请求,post请求)
step3、编写服务器端的处理程序,一般服务器只需返回部分的数据。
step4、编写事件处理函数
示例:焦点移开,检查用户名非空和唯一性
my.js
function getXhr(){ var xhr=null; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHttp'); } return xhr; }
regist.jsp
<html> <head> <script type="text/javascript" src="<%=request.getContextPath() %>/js/my.js"></script> <script type="text/javascript" src="<%=request.getContextPath() %>/js/prototype-1.6.0.3.js"></script> <script type="text/javascript"> function check_username(){ var username=$F('username'); if(username==""){ $("span_username").innerHTML="用户名不能为空。。"; }else{ var xhr=getXhr(); xhr.open("get","checkUsername.do?username="+username,true); xhr.onreadystatechange = function(){ if(xhr.readyState==4){ if(xhr.status==200){ var txt=xhr.responseText; $("span_username").innerHTML=txt; }else{ $("span_username").innerHTML="系统异常,稍后重试..."; } } }; $("span_username").innerHTML="正在检查。。。。"; xhr.send(null); } } </script> </head> <body> <fieldset> <legend>注册</legend> <form action="regist.do" method="post"> 用户名:<input type="text" name="username" onblur="check_username();" id="username"/><span style="color:red;" id="span_username">${regist_error }</span><br> 密码:<input type="password" name="pwd" onblur="check_pwd();"/><br> <input type="submit" value="注册" /> </form> </fieldset> </body> </html>
ActionServlet
public class ActionServlet extends HttpServlet{ protected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out=response.getWriter(); String uri=request.getRequestURI(); String action=uri.substring(uri.lastIndexOf('/'),uri.lastIndexOf('.')); if(action.equals("/checkUsername")){ Thread.sleep(5000); String username=request.getParameter("username"); if("张三".equals(username)){
out.println("用户名已经存在"); }else{ out.println("可以使用"); } }else if(action.equals("/regist")){ //任然要检查用户是否存在
String username=request.getParameter("username"); if("zs".equals(username)){ request.setAttribute("regist_error", "用户名被占用"); request.getRequestDispatcher("/regist.jsp").forward(request,response); }else{ System.out.println("注册"); }
} } }
prototype.js的简单使用
$(id);相当于document.getElementById(id);
$F(id);相当于 $(id).value
$(id1,id2..)依据id1,id2..查找对应的节点,然后将这些节点放到一个数组里面返回。
strip()除掉字符串两端的空格
evalJSON()将符合json语法格式的字符串转换成一个javascript对象。
发送post请求
xhr.open("post",url,true);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置一个消息头。发送post请求,要求浏览器发送一个Content-Type消息头。默认情况下,ajax对象(xhr)不会添加content-type消息头,所以调用setRequestHeader方法来添加这个消息头。
xhr.send("username="+name);
提示:有中文信息提交建议采用Post方式
在ajax应用当中的编码问题
发送get请求
产生乱码的原因
IE内置的ajax对象会使用“gbk”对中文进行编码,其他浏览器内置的ajax对象会使用“utf-8”对中文进行编码;服务器默认情况下,对于get请求发送过来的数据,会使“ISO-8859-1”进行解码。
解决方式
step1、让服务器使用指定的编码格式进行解码。比如:可以修改tomcat的配置文件conf/server.xml,添加URIEncoding="utf-8"
<Connector connectionTimeout="20000" port="8088" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>
step2、使用全局函数encodeURI函数对请求地址进行编码
xhr.open("get",encodeURI("check_username.do?username='张三'"),true);
发送post请求
xhr.open(‘post’,’check_username.do’,’true’);
乱码产生的原因
采用post请求方式,浏览器内置的ajax对象,对中文参数都使用”utf-8”进行编码。服务器端:如果是火狐发送请求,服务器端采用utf-8解码。其他浏览器是is0-8859-1解码。
因为发送的content-type消息头
火狐:Content-Type application/x-www-form-urlencoded; charset=UTF-8
其他:Content-Type: application/x-www-form-urlencoded;
火狐带有utf-8。这样服务器端采用utf-8解码,而不是iso-8859-1去解码
解决方式
服务器端:request.setCharacterEncoding="utf-8";
缓存问题
1. 什么是缓存问题?
在使用IE浏览器时,如果使用get方式发送请求,浏览器会将数据缓存起来。这样,当再次发送请求时,如果请求地址不变,IE不会真正地向服务器发请求,而是将之前缓存的数据显示给用户。只有IE浏览器才会有缓存问题
2. 解决方式:
a. 使用post方式(post请求不会缓存)
b. 为了避免缓存问题,可以在URL后面追加一组参数,该参数值可以使用随机值或者时间戳。随机值:Math.random() 时间戳:new Date().getTime()
同步问题
浏览器是单线程的,设置成同步之后,发送请求就一直等待服务器的处理结果、浏览器没有其他的线程来处理其他事。 一般数据验证的时候用同步请求。要等服务器返回数据后,才可以做其他事。