从零学习XHR

最近经常遇到要用javascript来发送请求,我们可以使用XHR对象来发送一个Ajax请求。


什么是XHR

XHR——XMLHttpRequest对象
XMLHttpRequest 对象用于在后台与服务器交换数据。

XHR可以干啥

在不重新加载页面的情况下更新网页
在页面已加载后从服务器请求数据
在页面已加载后从服务器接收数据
在后台向服务器发送数据

XHR兼容性

xhr兼容性

IE8/IE9、Opera Mini 完全不支持xhr对象
IE10/IE11部分支持,不支持 xhr.responseType为json
部分浏览器不支持设置请求超时,即无法使用xhr.timeout
部分浏览器不支持xhr.responseType为blob

如何开始使用XHR

创建XMLHttpRequest对象

通过一行简单的JavaScript代码,我们就可以创建XMLHttpRequest对象。
创建XMLHttpRequest对象的语法:

1
xhr = new XMLHttpRequest();

老版本的Internet Explorer(IE5和IE6)使用ActiveX对象:

1
xhr=new ActiveXObject("Microsoft.XMLHTTP");

使用XHR

请求方式

GET请求

1
2
3
4
5
6
7
8
var xhr = new XMLHttpRequest();
xhr.open("get","test.php?username=test&password=test&submit=submit",true);
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status ==200) {
alert(xhr.responseText);
}
};
xhr.send(null);

php页面:

1
print_r($_GET);

POST请求

1
2
3
4
5
6
7
8
9
10
11
var xhr = new XMLHttpRequest();
xhr.open("post","test.php",true);
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status ==200) {
alert(xhr.responseText);
}
};
//比GET请求多了一步
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//另外,数据是通过send方法发送的
xhr.send("username=test&password=test&submit=submit");

php页面:

1
2
header("Cache-Control: no-cache, must-revalidate");//可以让浏览器不缓存结果
print_r($_POST);

XHR对象参考

readyState属性

返回当前请求的状态:
0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
1 (初始化) 对象已建立,尚未调用send方法
2 (发送数据) send方法已调用,但是当前的状态及http头未知
3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误
4 (完成) 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var xhr =new XMLHttpRequest();
alert(xhr.readyState);//0
xhr.open("get","test.htm",true);
alert(xhr.readyState);//1
xhr.send(null);
alert(xhr.readyState);//IE下会是4,而FF下会是2
//可以通过readystatechange事件监听
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
alert(xhr.readyState);//Firefox下会依次是1,2,3,4但最后还会再来个1
//IE下则是1,1,3,4
};
xhr.open("get","test.txt",true);
xhr.send(null);

从上面可以看到,对于readyState这个属性,各个浏览器看法也不一样,但其实我们只需要知道当状态为4的时候可以获取response就行了!
status 返回当前请求的http状态码

response数据

xhr提供了3个属性来获取请求返回的数据,分别是:xhr.response、xhr.responseText、xhr.responseXM

xhr.response

默认值:空字符串””
当请求完成时,此属性才有正确的值
请求未完成时,此属性的值可能是””或者 null,具体与 xhr.responseType有关:当responseType为””或”text”时,值为””;responseType为其他值时,值为 null

xhr.responseText

默认值为空字符串””
只有当 responseType 为”text”、””时,xhr对象上才有此属性,此时才能调用xhr.responseText,否则抛错
只有当请求成功时,才能拿到正确值。以下2种情况下值都为空字符串””:请求未完成、请求失败

xhr.responseXML

默认值为 null
只有当 responseType 为”text”、””、”document”时,xhr对象上才有此属性,此时才能调用xhr.responseXML,否则抛错
只有当请求成功且返回数据被正确解析时,才能拿到正确值。以下3种情况下值都为null:请求未完成、请求失败、请求成功但返回数据无法被正确解析时

responseType

xhr.response数据类型 说明
“” String字符串 默认值(在不设置responseType时)
“text” String字符串
“document” Document对象 希望返回 XML 格式数据时使用
“json” javascript 对象 存在兼容性问题,IE10/IE11不支持
“blob” Blob对象
“arrayBuffer” ArrayBuffer对象

responseType是xhr level 2新增的属性,用来指定xhr.response的数据类型,目前还存在些兼容性问题
用xhr.response来获取一张图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
//可以将`xhr.responseType`设置为`"blob"`也可以设置为`" arrayBuffer"`
//xhr.responseType = 'arrayBuffer';
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
...
}
};
xhr.send();

abort

取消当前请求
abort方法在所有的XMLHttpRequest版本和XHR2中可用,调用abort方法在这个对象上触发abort事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function timeedGetText(url,timeout,callback){
var xhr = new XMLHttpRequest();
var timedout = false;
var timer = setTimeout(function(){
timedout = true;
xhr.abort();
},timeout);
xhr.onreadystatechange = function(){
if(xhr.readyState !=4){ return;}
if(timedout){ return;}
clearTimeout(timer);
if(xhr.status === 200){
callback(xhr.responseText);
}
};
}

getAllResponseHeaders

获取响应的所有http头 每个http头名称和值用冒号分割,并以\r\n结束。当send方法完成后才可调用该方法。

1
xhr.getAllResponseHeaders();//返回全部头信息,string

getResponseHeader

从响应信息中获取指定的http头 当send方法成功后才可调用该方法。如果服务器返回的文档类型为”text/xml”, 则这句话xmlhttp.getResponseHeader(“Content-Type”);将返回字符串”text/xml”。可以使用getAllResponseHeaders方法获取完整的http头信息。

1
2
3
4
xhr.getResponseHeader('date');
xhr.getResponseHeader('server');
xhr.getResponseHeader('transfer-Encoding');
xhr.getResponseHeader('content-type');

setRequestHeader

单独指定请求的某个http头 如果已经存在已此名称命名的http头,则覆盖之。此方法必须在open方法后调用。

1
xhr.setRequestHeader("User-Agent", "IOS99");

学习链接

传送门0x00,0x01

文章目录
  1. 1. 什么是XHR
  2. 2. XHR可以干啥
  3. 3. XHR兼容性
  4. 4. 如何开始使用XHR
    1. 4.1. 创建XMLHttpRequest对象
  5. 5. 使用XHR
    1. 5.1. 请求方式
      1. 5.1.1. GET请求
      2. 5.1.2. POST请求
  6. 6. XHR对象参考
    1. 6.1. readyState属性
    2. 6.2. response数据
      1. 6.2.1. xhr.response
      2. 6.2.2. xhr.responseText
      3. 6.2.3. xhr.responseXML
    3. 6.3. responseType
    4. 6.4. abort
    5. 6.5. getAllResponseHeaders
    6. 6.6. getResponseHeader
    7. 6.7. setRequestHeader
  7. 7. 学习链接