Ajax:Asynchronous JavaScript + XML 的简写,虽然名字包含 XML,但 Ajax 通信与数据格式无关。
【无须刷新页面即可从服务器取得数据】
核心:XMLHttpRequest 对象 (简称 XHR)
IE5 是第一款引入 XHR 对象的浏览器。在 IE5 中,XHR 对象是通过 MSXML 库中的一个 ActiveX 对象实现的。(旧款浏览器不多讨论)
IE7+、Firefox、Opera、Chrome 和 Safari 都支持原生的 XHR 对象。
创建 XHR 对象:
var xhr = new XMLHttpRequest();
open():启动请求
3个参数:要发送的请求的类型(“get”、"post"等)、请求的 URL 和表示是否异步发送请求的布尔值。
xhr.open("get", "example.php", false);
说明:
URL 相对于执行代码的当前页面(当然也可以使用绝对路径);
调用 open() 方法并不会真正发送请求,只是启动一个请求以备发送。
注意:
只能向同一个域中使用相同端口和协议的 URL 发送请求。
send():发送请求
1个参数:要作为请求主体发送的数据。
send(null);
注意:如果不需要通过请求主体发送数据,必须传入 null,因为这个参数对有些浏览器来说是必需的。
收到响应后,响应的数据会自动填充 XHR 对象的属性。
responseText:作为响应主体被返回的文本。
responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保存包含着响应数据的 XML DOM 文档。
status:响应的 HTTP 状态。
statusText:HTTP 状态的说明。
接收到响应后,第一步检查 status 属性,以确定响应已经成功返回。
一般来说,可以将 HTTP 状态代码为 200 作为成功的标志。此时,responseText 属性的内容已经就绪,在内容类型正确的情况下,responseXML 也应该能够访问了。
状态代码为 304 表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本。(也意味着响应是有效的)。
发送异步请求,检测 XHR 对象的 readyState 属性,该属性表示请求 / 响应过程的当前活动阶段。
0:未初始化。尚未调用 open() 方法。
1:启动。已经调用 open() 方法,但尚未调用 send() 方法。
2:发送。已经调用 send() 方法,但尚未接收到响应。
3:接收。已经接收到部分响应数据。
4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
readystatechange 事件:readyState 属性的值变化时就会触发
注意:必须在调用 open() 之前指定 onreadystatechange 事件处理程序,才能确保跨浏览器兼容性。
abort():在接收到响应之前,取消异步请求
xhr.abort();
调用后,XHR 对象会停止触发事件,也不再允许访问任何与响应有关的对象属性。
在终止请求之后,还应该对 XHR 对象进行解引用操作。由于内存原因,不建议重用 XHR 对象。
XHR 对象提供了操作两种头部(请求头部和响应头部)信息的方法。
默认情况下,在发送 XHR 请求的同时,还会发送下列头部信息。
不同浏览器实际发送的头部信息会有所不同,但下列信息基本上是所有浏览器都会发送的。
Accept:浏览器能够处理的内容类型。
Accept-Charset:浏览器能够显示的字符集。
Accept-Encoding:浏览器能够处理的压缩编码。
Accept-Language:浏览器当前设置的语言。
Connection:浏览器与服务器之间连接的类型。
Cookie:当前页面设置的任何 Cookie。
Host:发出请求的页面所在的域 。
Referer:发出请求的页面的 URI。
User-Agent:浏览器的用户代理字符串。
setRequestHeader():设置自定义的请求头部信息。
2个参数:头部字段的名称和头部字段的值。
注意1:要成功发送请求头部信息,必须在调用 open() 方法之后且调用 send() 方法之前调用 setRequestHeader()。
注意2:建议使用自定义的头部字段名称,不要使用浏览器正常发送的字段名称,否则有可能会影响服务器的响应。有的浏览器允许重写默认的头部信息,但有的浏览器不允许这样做。
getResponseHeader():传入头部字段名称,取得相应的响应头部信息。
getAllResponseHeaders():取得一个包含所有头部信息的长字符串。
在服务器端,也可以利用头部信息向浏览器发送额外的、结构化的数据。
GET 是最常见的请求类型,最常用于向服务器查询某些信息。
必要时,可以将查询字符串参数追加到 URL 的末尾,以便将信息发送给服务器。
查询字符串的格式问题:
查询字符串中每个参数的名称和值都必须使用 encodeURIComponent() 进行编码,然后才能放到 URL 的末尾;所有名值对都必须由和号(&)分隔。
向现有 URL 的末尾添加查询字符串参数的辅助函数:
function addURLParam(url, name, value) {
url += (url.indexOf("?") == -1 ? "?" : "&");
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
return url;
}
一个get请求代码:
var xhr = createXHR(); // var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get", "example.txt", true);
xhr.send(null);
POST 请求使用频率仅次于 GET,通常用于向服务器发送应该被保存的数据。
不同点:POST 请求应该把数据作为请求的主体提交,GET 请求传统上不是这样。POST 请求的主体可以包含非常多的数据,而且格式不限。
使用 XHR 模仿表单提交:首先将 Content-Type 头部信息设置为 application/x-www-form-urlencoded,也就是表单提交时的内容类型,其次是以适当的格式创建一个字符串(序列化)。
一个post请求代码:
var xhr = createXHR(); // var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("post", "postexample.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var form = document.getElementById("user-info");
xhr.send(serialize(form));
XMLHttpRequest 2 级定义了 FormData 类型,便于序列化表单以及创建与表单格式相同的数据(用于通过 XHR 传输)。
创建一个 FormData 对象:
var data = new FormData();
通过向 FormData 构造函数中传入表单元素,可以预先填入数据。
var data = new FormData(document.forms[0]);
append():向FormData 对象添加数据。
2个参数:键和值,分别对应表单字段的名字和字段中包含的值。
data.append("name", "Nicholas");
创建了 FormData 的实例后,可以将它直接传给 XHR 的 send() 方法。
var form = document.getElementById("user-info"); xhr.send(new FormData(form));
使用 FormData 的方便之处:不必明确地在 XHR 对象上设置请求头部。XHR 对象能够识别传入的数据类型是 FormData 的实例,并配置适当的头部信息。
支持 FormData 的浏览器:Firefox 4+、Safari 5+、Chrome 和 Android 3+版 WebKit。
XHR 对象添加了一个 timeout 属性,表示请求在等待响应多少毫秒之后就终止。(IE8+)
在给 timeout 设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发 timeout 事件,进而会调用 ontimeout 事件处理程序。
xhr.open("get", "timeout.php", true);
xhr.timeout = 1000; //将超时设置为1秒钟
xhr.ontimeout = function(){
alert("Request did not return in a second.");
};
xhr.send(null);
overrideMimeType():用于重写 XHR 响应的 MIME 类型。(Firefox 最早引入)
注意:调用 overrideMimeType() 必须在 send()方法之前,才能保证重写响应的 MIME 类型。
支持 overrideMimeType() 的浏览器:Firefox、Safari 4+、Opera 10.5 和 Chrome。
使用举例:服务器返回的 MIME 类型是 text/plain,但数据中实际包含的是 XML。根据 MIME 类型,即使数据是 XML,responseXML 属性中仍然是 null。调用 overrideMimeType() 修改 MIME 类型为 text/xml,保证把响应当作 XML 而非纯文本来处理。
6 个进度事件:
loadstart:在接收到响应数据的第一个字节时触发。
progress:在接收响应期间持续不断地触发。
error:在请求发生错误时触发。
abort:在因为调用 abort() 方法而终止连接时触发。
load:在接收到完整的响应数据时触发。
loadend:在通信完成或者触发 error、abort 或 load 事件后触发。
每个请求都从触发 loadstart 事件开始,接下来是一或多个 progress 事件,然后触发 error、abort 或 load 事件中的一个,最后以触发 loadend 事件结束。
浏览器支持:支持前 5 个事件的浏览器有 Firefox 3.5+、Safari 4+、Chrome、iOS 版 Safari 和 Android 版 WebKit。Opera(从第 11 版开始)、IE 8+只支持 load 事件。目前还没有浏览器支持 loadend 事件。
load 事件:响应接收完毕后将触发。可以替代 readystatechange 事件,没有必要再检查 readyState 属性。
onload 事件处理程序会接收到一个 event 对象,其 target 属性就指向 XHR 对象实例,因而可以访问到 XHR 对象的所有方法和属性。
progress 事件:在浏览器接收新数据期间周期性地触发。
onprogress 事件处理程序会接收到一个 event 对象,其 target 属性是 XHR 对象,但包含着三个额外的属性。
lengthComputable 是一个表示进度信息是否可用的布尔值,position 表示已经接收的字节数,totalSize 表示根据 Content-Length 响应头部确定的预期字节数。
创建进度指示器示例:
var xhr = createXHR(); // var xhr = new XMLHttpRequest()
xhr.onload = function(event){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
};
xhr.onprogress = function(event){
var divStatus = document.getElementById("status");
if (event.lengthComputable){
divStatus.innerHTML = "Received " + event.position + " of " + event.totalSize +" bytes";
}
};
xhr.open("get", "altevents.php", true);
xhr.send(null);