在IE7如下的浏览器,不支持原生XHR对象,须要使用MSXML库中的XHR对象,有三种不一样版本: MSXML2.XMLHttp、MSXML2.XMLHttp.3.0 和 MXSML2.XMLHttp.6.0。php
若是要兼容这些浏览器,必须建立一个函数来处理兼容问题。git
function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined"){ if (typeof arguments.callee.activeXString != "string"){ var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"], i, len; for (i=0,len=versions.length; i < len; i++){ try { new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; } catch (ex){ //跳过 } } } return new ActiveXObject(arguments.callee.activeXString); } else { throw new Error("No XHR object available."); } }
而后就能够使用var xhr = createXHR();
来在全部浏览器中建立XHR对象了。github
使用XHR对象,要调用的第一个方法是open()方法,用来初始化请求,接受三个参数,分别是请求类型、请求URL、是否异步发送请求。
xhr.open("get", "demo.php", true);
ajax
要发送get请求,必须接着调用send()方法:xhr.send(null);
。浏览器
因为是异步请求,须要检测一个状态,等待数据接收完毕再处理请求。这个状态经过readyState
来表示。
readyState的值能够取0/1/2/3/4,分别表明未初始化、启动、发送、接受、完成状态。每次readyState改变都会触发事件: readystatechange
。
注意,为了保证跨浏览器兼容性,须要在open方法以前指定 onreadystatechange
事件。服务器
var xhr = createXHR(); 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", 'demo.php', true); xhr.send(null);
对于get请求URL的查询字符串参数,能够使用encodeURIComponent
来将参数转化为合法的URL。并发
function addURLParam(url, name, value){ url += (url.indexOf("?") == -1 ? "?" : "&"); url += encodeURIComponent(name) + "=" + encodeURIComponent(value); return url; }
与get请求不一样的是,post请求须要在send方法中,传入数据参数。还须要设置http请求头信息,将Content-Type
设置为application/x-www-form-urlencoded
。app
function submitData(id){ var xhr = createXHR(); 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(id); // 将ID为id的表单中的数据序列化后发送给服务器 xhr.send(serialize(form)); // 将表单数据序列化并发送 }
serialize
表单序列化函数:异步
function serialize(form){ var parts = [], field = null, i, len, j, optLen, option, optValue; for (i=0, len=form.elements.length; i < len; i++){ field = form.elements[i]; switch(field.type){ case "select-one": case "select-multiple": if (field.name.length){ for (j=0, optLen = field.options.length; j < optLen; j++){ option = field.options[j]; if (option.selected){ optValue = ""; if (option.hasAttribute){ optValue = (option.hasAttribute("value") ? option.value : option.text); } else { optValue = (option.attributes["value"].specified ? option.value : option.text); } parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue)); } } } break; case undefined: //字段集 case "file": //文件输入 case "submit": //提交按钮 case "reset": //重置按钮 case "button": //自定义按钮 break; case "radio": //单选按钮 case "checkbox": //复选框 if (!field.checked){ break; } /* 执行默认操做 */ default: //不包含没有名字的表单字段 if (field.name.length){ parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value)); } } } return parts.join("&"); }
load
: 在接收到完整的响应数据时触发该事件。只支持IE8+以上的浏览器。函数
能够用来替代readystatechange
事件,响应接收完毕就触发load事件,所以没有必要去检查readyState
属性了。
var xhr = createXHR(); xhr.onload = function(){ if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful:" + xhr.status); } }; xhr.open("get", "demo.php", true); xhr.send(null);
详情请见笔记: JavaScript高级程序设计: Ajax