AJAX是什么
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
先来看看为什么要用ajax,了解同步和异步是什么:
同步的意思就是客户端提交表单,发起请求后需要一直等待服务器端的响应,收到服务器端的响应后需要重新载入页面。
而有了ajax,则可进行异步交互,比如不会提交整个表单后等待服务器响应再刷新页面,而是填写的过程中,通过ajax的机制,就可以把已经填写的部分提交给服务器,服务器进行处理,而这个过程中可以继续填写后面的内容,服务器发送回响应只会刷新页面的部分内容(利用JavaScript操作DOM进行局部刷新),而不是重新载入整个页面。
其实就是为客户机(网页中常为JavaScript)代码提供了一种发送HTTP请求的方式。通常提交请求都是以表单的形式发送,获取响应要刷新整页,而ajax则是按需发送,只刷新返回的数据。
Ajax指异步的JavaScript和XML,JS无需等待服务器响应,而是在继续执行脚本内容,响应就绪后对响应进行处理。若是同步,则JS代码会收到服务器的响应后再继续执行。
ajax是通过XMLHttpRequest对象在客户端和服务器端进行数据交换的。
1. 创建XMLHttpRequest对象
该对象用于和服务器交换数据:
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
2.向服务器发送请求
XHR.open(method,url,async):规定请求的方式、请求文件在服务 器上的URL和是否异步处理请求。启动一个请求以备发送。
Method:get和post(post用来传输数据)
url:要发送请求的地址;
async:声明发送的请求的方法(true、false)
XHR.send():将请求发送到服务器,参数为请求主体发送的数据,如果不需要请求主体发送数据,则必须填入null,因为对有些浏览器来说必须有一个参数。通常post方式会填入发送的数据。
3.服务器响应
在收到响应后,响应的数据会自动填充XHR对象的属性:
XHR.responseText:服务器返回的文本数据
XHR.responseXML:服务器返回的XML格式的数据
status:服务器返回的状态码。响应的HTTP状态:
- 200: “OK”,响应成功返回
- 304:请求的资源未被修改,可使用浏览器中的缓存版本
- 404: 未找到页面
statusText:HTTP状态文本说明
同步的时候应当检查status的值后来决定下一步的操作:
if(xhr.status>=200 && xhr.status<300 || xhr.status=304){
//do something
}else{
alert("request was unsuccessful: "+xhr.status);
}
4.异步处理
onreadystatechange 事件:当async为true时,规定该事件上绑定的方法,每当readyState属性改变时,就会触发该事件。
readyState属性:表示请求-响应过程的当前活动阶段。为XHR对象的状态。异步的时候应当检查该属性。从 0 到 4 发生变化:
0: 请求未初始化,未调用open()
1: 服务器连接已建立,已调用open,未调用send
2: 请求已接收,即服务器已收到请求头信息。 已调用send,尚未收到响应
3: 已收到部分响应数据
4: 请求已完成,已收到全部响应数据,可在客户端使用
注意:需在调用open之前指定onreadystatechange事件绑定的函数才能确保跨浏览器兼容性。
xhr.onreadystatechange=function(){
if(xhr.readyStatus==4){
if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
//do something
}else{
alert("request was unsuccessful: "+xhr.status);
}
}
}
5.终止异步
xhr.abort():调用该方法取消异步请求,XHR对象会停止触发事件,并且不再允许访问任何与响应有关的对象属性。
在终止请求后,应对XHR对象释放引用。
6.老版本的XHR对象缺点
只支持文本数据的传送,无法读取和上传二进制文件。
只能访问同域中的资源。
传送和接收数据时没有进度信息,只能提示有无完成。
新版本即level2的改进:
浏览器在发送XHR请求的同时也会默认发送一些头部信息,浏览器能够显示的字符集(Accept-charset)、当前页面设置的任何Cookie等。也可以自定义发送信息,通过调用XHR.setRequestHeader(header,value)向请求添加头部。该方法应当放在open之后send之前。
XHR对象的getResponseHeader()和getAllResponseHeaders()可用于获取响应的头部信息
1. GET请求
常用于向服务器查询某些信息,可将查询字符串参数追加到url末尾。必须对查询字符串进行encodeURIComponent()编码,具体来说必须对参数名和参数值都进行编码才能附加到url后面。
向现有url追加查询字符串参数:
functionaddURLPara(url,name,value){
url += (url.indexOf("?") == -1 ? "?":"&");
url += encodeURIComponent(name)+"="+encodeURIComponent(value);
return url;
}
2.POST请求
用于向服务器发送应当被保存的数据(修改服务器端数据),数据是请求的主体。
使用POST方式:
- 无法使用缓存文件(get通常会使用缓存?)
- 向服务器发送大量数据
- 发送包含未知字符的用户输入
在send方法中传入要发送的数据(字符串或文档)
表单数据序列化,通过XHR发送到服务器:
functionsubmitData(){
var xhr = createXHR();
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
//do something
}else{
alert("request was unsuccessful: "+xhr.status);
}
};
}
xhr.open("post","url",true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //表单提交时的内容类型,如果提交的是表单数据必须要写这个
var form = document.getElementById("user-info");
xhr.send(serialize(form));//表单序列化
}
使用该方式必须设置自定义请求头部信息Content-Type,以说明请求的内容类型。这样服务器就会根据请求的内容类型来解析表单中的数据。
在通过post方式请求表单中,在open和send之间,要添加request.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”)
如果不设置content-type头部,那么发送给服务器的数据就不会出现在$_POST超级全局变量中。
在来看看新一代的XHR即XHR2级对象又提供了哪些方法吧。
1. FormData类型
用于将表单数据序列化和创建和表单格式相同的数据:
方式一:
var data = new FormData();
data.append(“key”,”value”);
方式二:
var data = new FormData(form对象);
以上代码应该在open和send(data)之间。
2. overrideMimeType(“text/xml”)方法
重写服务器返回的MIME类型。强迫XHR对象将响应当做XML而非纯文本来处理
3.超时设定(IE8+支持)
XHR对象支持timeout属性和ontimeout事件处理程序。timeout属性用于设置请求等待响应的时间,若超出了则终止请求,然后触发timeout事件,调用ontimeout事件处理程序。
终止请求后readyState属性可能已经为4了,但是如果终止请求后再访问status属性(响应状态码)会报错,因此可将访问该属性的代码用try、catch括起来。
那么我们通过XHR对象传递的数据都有哪些格式呢?下面再来看看常用的几种数据格式。
XML是一种数据格式,在异步应用程序中常有以下两种用法:
一是以XML格式从网页发送HTTP请求给服务器
二是以XML格式在网页中接收服务器的响应
客户端发送请求
XML格式的请求和响应比普通文本慢,消耗内存更多,因为要添加标签和语义。
将数据包装为XML格式其实也是使用字符串的形式,不过字符串中有相应的标签。即发送的数据都必须是文本。
以XML格式化数据时应先设置请求头部:
xhr.setRequestHeader(“Content-type”,”text/xml”)。若果是发送普通文本则类型为text/plain
最好是使用普通文本的方式发送请求数据。
发送文本格式的请求(名/值对)和发送XML格式包装后的数据例子讲解:http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro7.html
服务器发送响应
比较适合用XML格式的数据,原因是若发送的响应为文本,其中包含多个名称/值对,服务器程序用某种符号连接这些对儿(没有一个标准),而客户端必须采取措施将这些响应文本(字符串)中的对儿依次解析出来。(而服务器端技术提供了多种方法来根据名称获取值,所以客户端发送请求时适合用名称/值对这种方式)。
XML响应可以是以XML格式化的纯文本,客户端中通过xhr.responseText属性来获取,这时仍出现了需要解析字符串的问题,所以不应该以这种方式来发送XML响应。应当使用XML文档,客户端可通过xhr.responseXML获取,将该文档当成一个DOM Document对象,在客户端可以利用DOM来解析该文档。
**json基本概念和格式
当需要在客户端和服务器端之间传递大量数据时,使用Json格式的数据会很灵活,便于解析。
Json是一种存储和交换文本信息的语法,采用键值对方式组织。Json是独立于语言的,可被任何语言解析和生成。
json和XML相比有这样一些优点:
长度短小,读写速度更快;可以使用JavaScript内建的方法进行解析,也可以直接转换成JavaScript对象,非常方便。
json数据的书写格式为名称-值这样的对儿:
"name":value
· 1
注意名称有引号,当value为字符串时也应该加引号。
value的数据类型可为:
· 数字
· 字符串
· 布尔值
· 数组(在[]中)
· 对象(在{}中)
· null
举一个json文件的例子:
{
"staff":[
{"name":"anna"},
{"name":"mike","age":10},
{"name":"lily","age":30}
]
}
最外层的大括号{}表示这是一个json对象。
**在JS中解析json
通过下述几种方式可以把一个json字符串解析为一个JavaScript对象。
(1)使用eval()解析
可以浏览器控制台中进行如下代码测验:
var jsondata='{"staff":[{"name":"anna","age":20},{"name":"mike","age":10},{"name":"lily","age":30}]}'; //注意这个json字符串要放到同一行;服务器端的返回的数据应该写成这样一个json对象字符串
var jsonobj=eval('('+jsondata+')'); //eval使用这种方式解析
alert(jsonobj.staff[0].name);
采用eval,不仅会解析成一个JavaScript对象,还会执行json字符串中的方法,例如把”age”:20改为”age”:alert(“hello”),则会执行这个alert语句。
(2)使用JSON.parse()解析
var jsonobj=JSON.parse(jsondata);
· 1
使用这种方式解析不会执行json字符串中的方法,会报错,json字符串语法不合法。
由于eval方法不会检查语法,这样很危险,如果接收的json数据中包含恶意代码会被执行。
检查json语法的格式化校验在线工具:jsonlint.com
该事件的作用是提供了与文档或元素的加载状态有关的信息。支持该事件的对象都有一个readyState属性。该属性有如下几个值:
uninitialized(未初始化):对象存在但尚未初始化
loading(正在加载):对象正在加载数据
loaded:对象加载数据完成
interactive:可以操作对象了,但韩没有完全加载
complete:对象已经加载完毕
并非所有的对象都会经历这几个阶段。
jQuery提供了三个层次的ajax方法,位于最底层的$.ajax()、第二层的$.load()、$.get()、$.post(),以及第三层的$.getScript()、$.getJson()。
先来说明第二层的方法。
1. $(‘selector’).load(url,data,function)方法
这个方法可以远程加载HTML代码并插入选中的DOM结点中。
其中data为object类型。
无论ajax请求有没有成功,请求完成后都会触发回调函数,该函数有三个参数:responseText,textStatus(sucsess,error,notmodified,timeout中的一种),XMLHttpRequest。
如果只需加载html文档中的部分元素,可在url后面传入选择器参数(第一个空格后的为选择器),指定要加载的部分:
$('#result').load('ajax/test.html #container');
· 1
调用方式为:$ele.load(url,data,function)即可将响应的html片段写入ele元素中。
回调函数会在HTML 已经被插入完时被调用,在每个匹配的元素上被调用一次,并且 this始终指向当前正在处理的 DOM 元素。
默认使用 GET 方式 , 如果data参数提供一个对象,那么使用 POST 方式。
2.$.get(url,data,function,type)和$.post()
这两个方法是全局函数,而非某个jQuery对象的函数。load方法常用于加载静态数据文件,如果要向服务器传递参数可以用这两个方法。
其中data为object类型,type为期待服务器返回的数据类型(html,xml等);回调函数只有请求成功即textStatus为success时才调用。该函数包括两个参数:data,textStatus。data为返回的数据,可以为xml文档、json文件、html片段等。
例子:
<formid="form1"action="#">
<p>评论:</p>
<p>姓名: <inputtype="text"name="username"id="username" /></p>
<p>内容: <textareaname="content"id="content" rows="2"cols="20"></textarea></p>
<p><inputtype="button"id="send"value="提交"/></p>
</form>
<div class='comment'>已有评论:</div>
<divid="resText" >
</div>
//JS代码为
<script>
$(function(){
$("#send").click(function(){
$.get("get1.php",{username:$('#username').val(), content:$('#content').val()},
function(data){
$("#resText").html(data);
});
})
});
</script>
当返回数据为XML文档时,可以像解析html文档一样解析其中的元素,先用$(data)将返回文档变成一个jQuery对象(data就相当于html DOM树中的document结点),然后可以使用jQuery中的相关方法获取到树中结点的值,再构造成html格式的字符串然后通过html()方法写入网页中。
当返回数据问json文件时,data就是一个可被JavaScript直接使用的数据,如果是一个对象,可直接使用data.proptertyname获取其中属性值,如果data是数组,则可通过data[index]访问其中的元素。
post方法与get结构相同,其区别有一下几个:
get是将参数附着在url后传递,而post则是作为请求的主体来传送。用get传递的数据会被浏览器缓存起来,不太安全。
3. $.getScript(url,[callback])和$.getJson(url,[data],[callback])
$.getScript用来加载JavaScript文件(有时候没有必要一次性加载完所有js文件,需要的时候再加载)。加载完后会自动执行。
回调函数会在成功加载js文件后执行。
$.getJson用于加载json文件,和$.getScript的函数结构一样。补充一点就是回调函数的参数data是获取到的Json文件对象。可使用全局方法$.each(data,function(index/key,ele/value))来遍历集合data(可为数组或对象)中的元素。
4. $ajax()
例子:
$("#save").click(function(){
$.ajax({
type:"POST",
url:"serverjson.php",
data:{ //传送给服务器的数据
name:$("#staffName").val(),
number:$("#staffNumber").val(),
sex:$("#staffSex").val(),
job:$("#staffJob").val()
},
dataType:"json", //期望服务器发送会的数据格式
//请求成功的回调函数,data为返回的数据
success:function(data){
if(data.success){
$("#createResult").html(data.msg);
}else{
$("#createResult").html("出现错误:"+data.msg);
}
},
//请求失败的回调函数,参数为XHR对象
error:function(jqXHR){
alert("发生错误:"+jqXHR.status);
}
})
})
所有jQuery的Ajax方法都返回一个XMLHTTPRequest对象的超集
附:jquery中的ajax方法参数
1.url:
要求为String类型的参数,(默认为当前页地址)发送请求的地址。
2.type:
要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。
3.timeout:
要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。
4.async:
要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。
5.cache:
要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。
6.data:
要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看 processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。
7.dataType:
上送到服务器时的数据类型可选项:
Text,
Json
例子:data:{name:”admin”,password:”123456”}
datatype:json
正常是要加上datatype:json
如果没有申明数据类型,需要转换
JSON.stringsty()
要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
xml:返回XML文档,可用JQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
json:返回JSON数据。
jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。
8.beforeSend:
要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。
function(XMLHttpRequest){
this; //调用本次ajax请求时传递的options参数
}
9.complete:
要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
function(XMLHttpRequest,textStatus){
this; //调用本次ajax请求时传递的options参数
}
10.success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。
function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //调用本次ajax请求时传递的options参数
}
11.error:
要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:
function(XMLHttpRequest, textStatus,errorThrown){
//通常情况下textStatus和errorThrown只有其中一个包含信息
this; //调用本次ajax请求时传递的options参数
}
12.contentType:
要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
13.dataFilter:
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
function(data, type){
//返回处理后的数据
return data;
}
14.dataFilter:
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
function(data, type){
//返回处理后的数据
return data;
}
15.global:
要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。
16.ifModified:
要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。
17.jsonp:
要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。
18.username:
要求为String类型的参数,用于响应HTTP访问认证请求的用户名。
19.password:
要求为String类型的参数,用于响应HTTP访问认证请求的密码。
20.processData:
要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。
21.scriptCharset:
要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。