Ajax
1. Ajax简介
Ajax的全称是AsynchronousJavaScript and XML(异步的 JavaScript 和 XML)
为什么要有Ajax?
明白了Ajax的需求,就大致明白Ajax是干什么的了
一般情况下,浏览器提交了一个HTML请求以后,是怎么处理的?
浏览器会选择使用一个新的页面来打开服务器返回过来的数据。
就算form也是,在没有iFrame之前,form只能在target属性里面,定义是在当前窗口还是新窗里面打开这个请求返回的数据。
有一个需求是,我想在一个前端页面提交HTTP请求,然后在当前页面就显示请求的返回数据。而不是每次跟服务器交互都要重新打开一个新窗,或完全地重新刷新页面。
这时候Ajax技术就派上用场了,这个技术实现的某些功能其实以前学的IFrame也可以做,不过Ajax更大势。
目前很多网页,尤其社交网站,都会使用Ajax的技术,例如微博,你可以在不刷新页面的情况下,获取新微博,新评论等消息,就是通过Ajax来实现的。
Ajax是一种主要应用于前端的技术
2. 基本Ajax(不带jQuery)
2.1. 简单的程序案例:
<html>
<head>
<script type="text/javascript">
functionloadXMLDoc()
{
var xmlhttp;
if(window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome,Opera, Safari
xmlhttp=newXMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=newActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","/ajax/demo_get.asp",true);
xmlhttp.send();
}
</script>
</head>
<body>
<h2>AJAX</h2>
<button type="button"onclick="loadXMLDoc()">请求数据</button>
<div id="myDiv"></div>
</body>
</html>
2.2. 代码片段分析:
创建对象
在IE7+以及大部分的浏览器里面,使用这个语句来创建对象
xmlhttp=new XMLHttpRequest();
IE6、5使用的是这个方法:
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
为了兼容性,采用了if else 来进行判断。
if(window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome,Opera, Safari
xmlhttp=newXMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=newActiveXObject("Microsoft.XMLHTTP");
}
若window.XMLHttpRequest这个对象存在,就可以使用第一种方法创建Ajax对象。
Ajax对象包含了方法跟属性,来处理异步的HTTP请求。
创建请求
xmlhttp.open("GET","/ajax/demo_get.asp",true);
XMLHttpRequest对象调用open方法来给XMLHttpRequest对象定义一个请求的参数。
第一个参数,字符串,表示HTTP请求的方法,一般是GET或者POST
第二个参数,字符串,接收请求的URL
第三个参数,布尔型变量,决定请求是否是异步的,一般是true,这一点后面会有较详细的解释。
发送请求
xmlhttp.send();
简单直接,调用完open方法以后调用这句就可以发送请求。
获取请求的返回信息
使用XMLHttpRequest对象发送的请求,返回的信息不会直接在浏览器里面渲染,而是会以txt或者XML的形式返回给一个变量,再由浏览器这边的程序来确定如何处理请求返回来的内容。
如果返回的信息是普通的文本,可以使用这个方法来读取文本信息:
xmlhttp.responseText
这是一个String对象。
如果是XML,可以通过xmlhttp.responseXML来获取返回内容
这是一个XML对象。
XML对象可以有一些方法方便地处理XML文本。参见XML对象的相关知识。
*关于异步发送请求和XMLHttpRequest对象的readyState
这里是在Ajax中最需要注意的,因为JavaScript跟别的语言不一样,有异步机制。也就是说,JavaScript里面的代码不一定是按照代码的顺序执行的。使用异步的时候,你写下代码:
xmlhttp.send();
alert();
很可能先执行alert,后发送请求。
也就是说,发送请求这个动作并不会使程序阻塞。程序不会等请求发送完再进行其他动作,而是发送请求这一步跟程序里面其他动作轮着执行。类似机制的函数有image对象的onload方法。
对于这种异步回调的函数,为了让其他代码可以知道这个函数执行完了没,会有一些属性或方法来返回这个函数的执行状态。
而XMLHttpRequest对象里面有一个属性:readyState来记录当前在发送的HTTP请求的状态。
readyState有5种状态,用数字0到4表示。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
上面这几步代表了在后台执行异步HTTP请求发送的时候所经过的大致过程,当一个步骤完成了以后,readyState的值会改变,别的函数可以通过读取XMLHttpRequest对象的readyState的值,知道这个对象的发送请求函数进行到了哪一步。当状态是4的时候,才可以读取请求对象的response。
而XMLHttpRequest对象有一个函数,onreadystatechange,这个函数每一次XMLHttpRequest对象的readyState改变的时候,这个函数就会被调用。异步的发送请求需要在这里添加请求发送完毕以后的处理函数。异步发送的时候,不等请求的状态到4就会执行后续的语句。
而同步发送的方式,则可以直接在执行完send语句以后添加处理返回内容的语句。
例如:
xmlhttp.open("GET","/test/test",false);
xmlhttp.send();
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
因为同步方式的时候,请求状态到了4以后才会执行下一步的操作。
样例:为了体现出两者的差异,在服务器端,设置接收到请求5秒以后在发送
protectedvoiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {
// TODOAuto-generated method stub
try {
Thread.sleep(5000);
response.getWriter().println("finish");
} catch(InterruptedException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
当前端页面添加语句:
xmlhttp.open("GET","/test/test",false);
xmlhttp.send();
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
alert();
页面会在5秒后,有数据返回的时候,才进行弹窗
如果代码是:
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","/test/test",true);
xmlhttp.send();
alert();
那么会先弹窗,后显示返回的内容。
注意:浏览器在发送请求的时候,会优先根据缓存,直接拿出以前的返回结果,也就是说,提交过一次请求以后,再点一次按钮提交请求的时候,不会等5秒才返回数据,而是直接显示“finish”,这个实验要清空浏览器缓存才有效。
若使用语句:
xmlhttp.open("GET","/test/test",true);
xmlhttp.send();
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
alert();
那么动态提交请求的时候,不会自动把数据写回来,会报错。因为执行
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
这句的时候,xmlhttp对象还没有返回内容。
2.3. Ajax与iFrame的差别
IFrame可以直接访问别的域的资源,Ajax不可以
会报错:
17:10:08.995 已阻止跨源请求:同源策略禁止读取位于http://223.6.250.239/x/2/mall/get 的远程资源。(原因:CORS 头缺少'Access-Control-Allow-Origin')。1 <未知>
实现的机制不同,在IFrame里面,IFrame里面的相当于一个新页面,Ajax则是通过JavaScript来发送请求,受同源策略的影响。(同源策略就是,不能通过JavaScript来获取别的域名的资源,为的是防止JavaScript获取其他页面(邮箱等)的信息)
2.4. 小结
Ajax比单纯的form要灵活很多。
可以看到,Ajax其实跟普通的Java等后台语言发送网络包的过程类似。也是创建对象,提交请求,编辑报头,提交的内容这么几步,懂得用其他程序发送网络包的原理的话,这些上手就很快了。
由于同源策略,对于向外发送网络包还是不太好弄。
3. Ajax jQuery
怎样使用jQuery发送动态HTTP请求
参考:http://w3school.com.cn/jquery/jquery_ajax_get_post.asp
$.get()和$.post()方法
$.get()方法和$.post()方法的参数不一样
因为GET方法即使有参数,也可以在URL里面体现,所以只有两个参数:
$.get(URL,callback);
Callback是一个函数,用来处理请求返回来的数据。
更详细的信息查看这里:http://w3school.com.cn/jquery/ajax_get.asp
其实get和post方法都是对jQuery的$.ajax()方法的包装。
若想对请求报头什么的用更底层的方法去定义,可以用$.ajax方法
参考:http://w3school.com.cn/jquery/ajax_ajax.asp
更多细节可以参考:http://w3school.com.cn/jquery/jquery_ref_ajax.asp
怎样使用jQuery实现动态加载
使用jQuery不仅可以动态发送普通的get,post请求,还能够实现动态加载。
可以参考:http://w3school.com.cn/jquery/jquery_ajax_load.asp
使用语句:
$(selector).load(URL,data,callback);
必需的 URL 参数规定您希望加载的 URL。
可选的 data 参数规定与请求一同发送的查询字符串键/值对集合。
可选的 callback 参数是 load() 方法完成后所执行的函数名称。
jQuery的load方法不仅针对文字跟XML,也可以动态加载图片,文本文件等。
使用起来更强大。
后记
上面引用了很多http://w3school.com.cn的资源。对于开发来说,这个网站就是字典一样的神器。想不起哪个函数就上去查,感觉自己都要变懒了……