原生Ajax(兼容)
function ajax(options){
options = options||{};
var xhr = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new ActiveXObject("Microsoft.XMLHTTP")) ;
//onreadystatechange事件放在open()前,确保跨浏览器兼容性
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300){
...
}else{
...
}
}
}
//启动一个请求以备发送
xhr.open('get/post','example.php',true);
//设置请求头
xhr.setRequestHeader(...);
//发送数据
xhr.send(null);
}
GET和POST的区别,何时使用POST
GET:一般用于信息获取,查询字符串参数追加在URL末尾,对所发送信息的数量也有限制,一般在2000个字符;
//向现有URL末尾追加查询字符串
function addURLParam(url,name,value){
url += (url.index('?')==-1?'?':'&');
url += encodeURIComponent(name)+'='+encodeURIComponent(value);
return url;
}
POST:一般用于向服务器发送应该被保存的数据,对所发送的数据没有数量和格式的限制。
注:服务器对POST请求和提交web表单的请求不会一视同仁。
使用XHR来模仿表单提交
//XMLHttpRequest 1级写法
...
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)); //serialize见页末
//XMLHttpRequest 2级写法
...
xhr.open('post','postexample.php',true);
var form = document.getElementById('user-info');
xhr.send(new FormData(form));
与get请求相比,post请求消耗的资源会更多一些,从性能角度,以发送相同的数据比较,get的请求速度最多可达到post的两倍。
GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
然而,在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠。
xhr其它的一些方法
超时设定timeout及其事件
重写XHR响应的MIME类型 overrideMimeType()
进度事件
load可以替代readystatechange
progress 在接收响应期间不断地触发,会接收到一个event对象,它有三个属性:lengthComputable(进度信息是否可用,布尔值)、position(已接收的字节数)、totalSize(预期接收的总字节数)。
实例:进度指示器
...
xhr.onprogress = function(event){
var divS = document.getElementById('status');
if(event.lengthComputable){
divS.innerHTML = event.position + '/' + event.totalSize
}
}
...
//表单序列化 (了解)
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://默认处理,要求必须有name属性
if(field.name.length){
parts.push(encodeURIComponent(field.name)+"="+
encodeURIComponent(field.value));
}
}
}
return parts.join("&");
}