AJAX
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。AJAX 是在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的方法。
XMLHttpRequest 对象
为了使用JavaScript向服务器发送一个http请求,你需要一个包含必要函数功能的对象实例。这就是为什么会有 XMLHttpRequest
的原因。
XMLHttpRequest
是一个 API,它为客户端提供了在客户端和服务器之间传输数据的功能。它提供了一个通过 URL 来获取数据的简单方式,并且不会使整个页面刷新。这使得网页只更新一部分页面而不会打扰到用户。XMLHttpRequest
在 AJAX 中被大量使用。 虽然名字含有XML
,但该对象可以接受任何数据类型而不仅仅为XML,而且它支持的协议类型不限于HTTP(包括file,ftp)
如果你的连接涉及从服务器接收事件或者数据,可以考虑采用通过 EventSource
接口使用 server-sent events 服务器事件。至于全双工通信,使用WebSockets 是一个更好的选择。
创建 XMLHttpRequest 对象
所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象,老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象。
创建 XMLHttpRequest 对象的语法:
variable=new XMLHttpRequest(); //现代浏览器
variable=new ActiveXObject("Microsoft.XMLHTTP");//IE5 和 IE6
兼容性写法:
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");
}
向服务器发送请求
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:
xmlhttp.open("GET","test1.txt",true);
xmlhttp.send();
open()
的第一个参数是HTTP请求方法 - 有GET,POST,HEAD以及服务器支持的其他方法。 保证这些方法一定要是大写字母,否则其他一些浏览器(比如FireFox)可能无法处理这个请求。更多关于HTTP的请求方法,可以查看 W3C specs。open()
的第二个参数是你要发送的URL。由于安全原因,默认不能调用第三方URL域名。 确保你在页面中使用的是正确的域名,否则在调用open()
方法是会有 “权限被拒绝” 错误提示。一个容易犯的错误是你企图通过domain.tld
访问网站, 而不是使用www.domain.tld
。如果你真的需要向另一个域名发送请求, 可以查看 HTTP access control。open()
的第三个参数是可选的,用于设置请求是否是异步的。如果设为true
(默认设置),JavaScript执行会持续,并且在服务器还没有响应的情况下与页面进行交互。
方法 | 描述 |
---|---|
open(method,url,async) | 规定请求的类型、URL 以及是否异步处理请求。
|
send(string) | 将请求发送到服务器。
|
GET 还是 POST?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
在使用GET方法时,有可能获取到的是缓存的结果,为了避免这种情况,可 URL 添加一个唯一的 ID,比如
if(method == 'GET') {
//为了避免GET得到的是缓存的结果,请向 URL 添加一个唯一的 ID:
var date = new Date(),
imer = date.getTime();
xhr.open(method, url + '?' + data + '&timer=' timer, flag);
xhr.send();
}
如果希望通过 GET 方法发送信息,请向 URL 添加信息:
xmlhttp.open("GET","demo_get2.asp?fname=Bill&lname=Gates",true);
xmlhttp.send();
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:
xmlhttp.open("POST","ajax_test.asp",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Bill&lname=Gates");
这里有一篇文章:Ajax中application/x-www-form-urlencoded字符说明
监听并处理服务器响应
服务器在接受并处理数据的各阶段状态的切换都会触发XMLHttpRequest的onreadystatechange 事件,为这个事件绑定函数我们就可以获取到数据。
readyState状态值都在 XMLHTTPRequest.readyState中,以下是5中状态码
值 | 状态 | 描述 |
0 | UNSENT (未打开) | open() 方法还未被调用. |
1 | OPENED (未发送) |
|
2 | HEADERS_RECEIVED (已获取响应头) | send() 方法已经被调用, 响应头和响应状态已经返回. |
3 | LOADING (正在下载响应体) | 响应体下载中; responseText 中已经获取了部分数据. |
4 | DONE (请求完成) | 整个请求过程已经完毕. |
当readyState状态值等于4时,说明服务器已完成并且响应已准备好。这时候就看看服务器到底返回了什么
//绑定响应事件
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
//服务器响应完成
}
}
服务器将内容返回回来后,只有当状态码等于200时说明返回成功,其他请参考。。。
如果状态码为200,这时候可以获取正常的响应数据
if(xhr.status == 200){
callback(JSON.parse(xhr.responseText));
} else {
console.log('获取数据错误,错误状态码:' + xhr.status);
}
在检查完请求状态和HTTP响应码后, 你就可以用服务器返回的数据做任何你想做的了。你有两个方法去访问这些数据:
httpRequest.responseText
– 服务器以文本字符的形式返回httpRequest.responseXML
– 以 XMLDocument 对象方式返回,之后就可以使用JavaScript来处理
封装一个Ajax方法
/**
* ajax方法
* @param {string} method [使用GET 还是POST]
* @param {string} url [访问的网址]
* @param {string/number} data [传递的参数]
* @param {function} callback [当数据获取回来时候的回调函数]
* @param {boolean} flag [是否为异步加载]
*/
function ajax(method, url, data, callback, flag){
if(flag == undefined){ //如果用户没有传入flag值,默认为异步请求
flag = true;
}
//XMLHttpRequest 对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHttp');
}
//绑定响应事件
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if(xhr.status == 200){
callback(JSON.parse(xhr.responseText));
} else {
console.log('获取数据错误,错误状态码:' + xhr.status);
}
}
}
//发送请求
method = method.toUpperCase();
if(method == 'GET') {
//为了避免这种情况得到的是缓存的结果,请向 URL 添加一个唯一的 ID:
var date = new Date(),
timer = date.getTime();
xhr.open(method, url + '?' + data + '&timer=' timer, flag);
xhr.send();
} else if(method == 'POST') {
xhr.open(method, url, flag);
//以表单方式提交哦
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.send(data);
}
}