一、XMLHttpRequest对象
function createXHR(){
//适用于IE7+,Firefox,Opera,Chrome和Safair
if (typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
//适用于IE7之前的版本
} 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){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
1.1、XHR用法
- 创建XHR:createXHR()
- 使用XHR对象时,要调用的第一个方法时open(),它接收三个参数:要发送的请求类型(“个体”,“post”),请求的URL和表示是否异步发送请求的布尔值
- xhr.send():接收一个参数,即要作为请求主体发送的数据,如果不需要发送数据,传入null
- 调用send()之后,Javascript代码会等到服务器相应之后再继续执行。收到响应后,响应的数据会自动填充XHR对象的属性,相关的属性如下:
responseText:作为响应主体返回的文本
responseXML:响应内容是text/xml或者application/xml
status:响应的HTTP状态
statusText:HTTP状态的说明
var xhr=createXHR();
xhr.open("get","example.txt",false)
xhr.send(null)
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.responseText)
}else{
console.log("Response was unsucessful:"+xhr.status)
}
像这样发送同步请求当然没有问题,但在多数情况下,我们还是要发送异步请求,才能让Javascript继续执行而不必等待响应,此时,可以检测XHR的readyState属性,该属性表示请求/响应过程的当前活动阶段
0:未初始化,尚未调用open()方法
1:启动,已经调用open(),但尚未调用send()
2:发送,已经调用send(),但未接收到响应
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){
console.log(xhr.responseText)
}else{
console.log("Response was unsucessful:"+xhr.status)
}
}
}
xhr.open("get","example.txt",false)
xhr.send(null)
1.2、HTTP头部信息
XHR对象也提供了操作这两种头部(请求头部和响应头部)信息的方法
除了一些默认的HTTP头部信息,还可以自定义头部信息,使用setRequestHeader()方法,这个方法接收两个参数,头部字段的名称和头部字段的值。要成功发送请求头部信息,必须调用open()方法之后且调用send()方法之前调用
调用XHR对象的个体Response Header()方法并传入头部字段名称,可以获取响应的响应头部信息,而调用getAllResponseHeaders()可以取得一个包含所有头部信息的长字符串
var xhr=createXHR();
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
console.log(xhr.getAllResponseHeaders())
}else{
console.log("Response was unsucessful:"+xhr.status)
}
}
}
xhr.open("get","example.php",false)
xhr.setRequestHeader("MyHeader","MyValue")
xhr.send(null)
1.3、get请求
// 创建ajax对象
var xhr = createXHR()
xhr.onreadystatechange = function(event){
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
console.log(xhr.responseText);
} else {
console.log("Request was unsuccessful: " + xhr.status);
}
}
};
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// 拼接请求参数
var params = 'username='+ nameValue +'&age=' + ageValue;
// 配置ajax对象
xhr.open('get', 'http://localhost:3000/get?'+params);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencode")
// 发送请求
xhr.send();
// 获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
1.4、post请求
// 创建ajax对象
var xhr = createXHR()
xhr.onreadystatechange = function(event){
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
console.log(xhr.responseText);
} else {
console.log("Request was unsuccessful: " + xhr.status);
}
}
};
// 获取用户在
//获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// 拼接请求参数
var params = 'username='+ nameValue +'&age=' + ageValue;
// 配置ajax对象
xhr.open('post', 'http://localhost:8000/post');
// 设置请求参数格式的类型(post请求必须要设置)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 发送请求
xhr.send(params);
// 获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
二、XMLRequest
2.1、formData
序列化表单以及创建与表单格式相同的数据
formData.get(key)
formData.post(key,value)
// 将普通的html表单转换为表单对象
var formData = new FormData(form);
// 创建ajax对象
var xhr = createXHR()
xhr.onreadystatechange = function(event){
if (xhr.readyState == 4){
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
console.log(xhr.responseText);
} else {
console.log("Request was unsuccessful: " + xhr.status);
}
}
};
// 获取用户在
// 对ajax对象进行配置
xhr.open('post', 'http://localhost:2000/formData');
// 发送ajax请求
xhr.send(formData);
}
timeout属性
xhr.open("get", "timeout.php", true);
xhr.timeout = 1000;
xhr.ontimeout = function(){
alert("Request did not return in a second."); };
xhr.send(null);
上述这个例子意味着如果请求在1s内还没有返回,就会自动终止
2.2、overrideMimeType()方法
用于重写XHR响应的MIME类型,如果服务器没有指定一个Content-Type 头, XMLHttpRequest 默认MIME类型为"text/xml". 如果接受的数据不是有效的XML,将会出现格”格式不正确“的错误。你能够通过调用 overrideMimeType() 指定各种类型来避免这种情况。
// Interpret the received data as plain text
req = new XMLHttpRequest();
req.overrideMimeType("text/plain");
req.addEventListener("load", callback, false);
req.open("get", url);
req.send();
三、进度事件
loadstart:在接收到响应数据的第一个字节时触发
progress:在接受响应期间持续不断的触发
error:在请求发生错误时触发
abort:在因为吊影abort()方法而终止连接时触发
load:在接收到完整的响应数据时触发
loadend:在通信完成或者触发error,about,load事件后触发
2.3.1、load事件
使用onload代替onreadystate,就无需在使用readyState进行检测了
function submitData(){
var xhr = createXHR();
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.open("post", "http://localhost/post", true);
var form = document.getElementById("user-info");
xhr.send(new FormData(form));
}
2.3.2、progress事件
这个事件会在浏览器接收数据期间触发,而onprogress事件处理程序会接受到一个event对象,其target属性时XHR对象,但包含三个额外的属性:lengthComputable,position,totalSize,其中lengthComputable表示进度信息是否可用的布尔值,position表示已经接受的字节数,titalSize表示根据Content-Lenght响应头部确定的预期字节数
xhr.onprogress=function(event){
var divStatus=document.getElementById("status");
if(event.lengthComputable){
divStatus.innerHTML="Received"+event.position+"of"+event.totalSize+"bytes"
}
}
四、跨域资源共享
4.1、IE对CORS的实现
只支持异步请求
//创建一个XDR实例
var xdr=new XDomainRequest();
xdr.onload=function(){
//接收到响应后,只能访问响应原始文本,不能访问撞他怠慢
console.log(xdr.responseText)
}
xdr.open("get","http://www.somewhere-else.com/page/")
xdr.send(null)
为支持post,还有一个ContentType属性
4.2、其他浏览器对CORS的实现
无需编写其他代码,浏览器实现了对CORS的原生
支持同步异步请求,可以访问status和statusText属性
4.3、跨浏览器的CORS
检测XHR是否支持CORS的最简单的方式,就是检查是否存在withCredentials属性
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
}
else {
xhr = null;
}
return xhr;
}