原文地址:http://www.luckyjing.com/posts/js/ajax.html
Ajax终结了“单击,等待”的交互模式,它那么神奇,我们怎么会不爱它?根据大牛的观点结合自己的经验,希望给大家和未来的自己一份比较好的Ajax参考文章。
什么是Ajax?为什么要使用它?
Ajax全称 Asynchronous(异步) JavaScript and XML,终结了“单击,等待”的交互模式,它是指一种创建交互式网页应用的网页开发技术,Ajax并不是一种技术,它是一系列规范的集合,包含:
- 基于web标准(standards-basedpresentation)XHTML+CSS的表示;
- 使用 DOM(Document ObjectModel)进行动态显示及交互;
- 使用 XML 和 XSLT 进行数据交换及相关操作;
- 使用 XMLHttpRequest 进行异步数据查询、检索;
- 使用 JavaScript 将所有的东西绑定在一起。
Ajax应用程序的优势在于:
- 通过异步模式,提升了用户体验
- 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用
- Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。
基础-HTTP协议
在使用Ajax之前,必须先了解客户端和服务器间通信的基础是怎样的,在这里,他们使用的规则是HTTP协议,两者之间通过一定格式的报文(请求报文和响应报文)进行交流,详细的看这篇文章。链接:http://www.jianshu.com/p/81632fea327c
核心-XMLHttpRequest对象
支撑起Ajax大桥的便是XHR这个对象了,它是一种支持异步请求的技术。简而言之,XmlHttpRequest可以让JavaScript向服务器提出请求并处理响应,而不阻塞用户。通过XMLHttpRequest对象,Web开发人员可以在页面加载以后进行页面的局部更新。
在使用它之前,我们先来了解一下XHR对象,简单起见。关于不同浏览器之间的XHR对象暂时不叙述,直接使用原生XHR对象,在浏览器里面创建一个新的XHR对象var xhr = new XMLHttpRequest();
,在调试窗口里面输出它可以看到:
它是一个对象,拥有一些属性,常见的如下:
- readyState:该属性表示请求/响应过程的当前活动阶段,可用取值如下:
0:请求未初始化(还没有调用 open())。
1:请求已经建立,但是还没有发送(还没有调用 send())。
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
3:请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
4:响应已完成;已经接收到全部响应数据,而且已经可以在客户端使用了。
只要readyState属性的值发生变化,便可以触发readystatechange事件,下面来体验一下。
//演示readystatechange事件
var log = function(tmp){
console.log(tmp);
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
log(xhr.readyState);
};
xhr.open("get","./content.txt",true);
xhr.send(null);
观察运行结果,可以很明确地看到状态的发生改变。
responseText:作为响应主体被返回的文本,无论内容类型是什么,响应主体的内容都会保存在这里。
responseXML:如果响应的内容类型是
text/xml
或application/xml
,这个属性中将保存着响应数据的XML DOM文档。status:响应的HTTP状态,就是HTTP的状态代码,200,304(表示请求的资源没有被修改,可以直接使用浏览器中缓存的版本)这些,确保接收到适当的响应。
statusText:HTTP状态的说明
基础用法
var xhr = new XMLHttpRequest();
//创建一个XHR对象
xhr.open("get","test.txt",true);
//启动一个请求以备发送,这个时候xhr的readyState为1
xhr.send(null);
//正式发送请求,readyState为2,随后请求成功,readyState为4
我们来详细说一下细节。
- 首先是open方法:
第一个参数是HTTP的请求方式,常用的比如get
和post
,第二个参数是请求的url,如果是get
方式的话那么一般请求的参数就附加在这里。第三个参数是控制同步或者异步,true
表示异步,false
表示同步。简单来说,如果使用同步的话,那么会阻塞后面的代码,必须等到本次请求完毕才可以,异步则是另开一个线程去执行ajax,下面代码继续进行。 - 再说send方法:
send方法有一个参数,这个参数将被写入到请求报文
里面传递,上面说到了get
方式的参数是直接写到url里面的,所以对于这种方法,send的参数应该为null
,而对于post方式,url和请求参数是分离的,所以需要写入到send方法里。
HTTP头部信息
我们可以使用已有的API来对上面创建的请求报文进行增添或对响应报文进行处理,比如设置Cookie。
xhr.setRequestHeader("imake","myValue");//添加头部信息
xhr.getResponseHeader(headerName);//获取头部信息
xhr.getAllResponseHeaders();//获取全部头部信息
GET请求
GET方法将需要查询的字符串追加到URL的末尾,也就是在XHR的open方法的URL末尾进行添加,需要进行encodeURIComponent()
处理,对此封装函数如下:
function addURLParam(url,name,value){
url+=(url.indexOf("?") == -1 ? "?" : "&");
url+=encodeURIComponent(name)+"="+encodeURIComponent(value);
}
xhr.open("get",url,true);
POST请求
讨论POST之前,我们先回想一下,POST主要用在表单提交,表单提交的写法很多,比如:
<button>提交</button>
<input type="submit" value="提交">
<div id="submit">我用来提交表单</div>
var sub = document.getElementById("submit");
sub.addEventListener("click",function(){
document.getElementById("test").submit();
});
前两种方式在使用的时候非常不便,比如我们再检测它们点击之前需要进行表单验证,那么因为它们自身具有默认的提交功能,所以我们得把它们的默认功能阻止一下,所以使用第三种比较舒服。
在表单进行post时,背地里它将请求的Content-Type
设置为了application/x-www-form-urlencoded
(这种类型是上传不了文件的,先挖个坑),并且把表单序列化了。我们来演示一下:
明白了传统的post表单提交之后,我们来说说Ajax,其实它也是模仿表单提交,所以要主动地告诉服务器,我是post方式,比较复杂,你做好准备,所以要设置
Content-Type
头部信息为application/x-www-form-urlencoded
,其次是对表单进行序列化,我们可以使用jQuery里面的serialize()
方法,测试如下: