XMLHttpRequest综述

XMLHttpRequest在维基百科的定义”XMLHttpRequest (XHR) is an API in the form of an object whose methods transfer data between a web browser and a web server.” 它是一个在服务端和客户端之间进行传输数据的浏览器接口,说白了就是HTTP(S)的通信,依赖于浏览器的javascript环境。通信的数据格式限于XML,JSON,HTML,plain text。
但是这个接口的最初版本,各个浏览器厂家的实现也不尽相同,没有被标准化。这么下去也不是个事儿,技术总得进步,接口总得统一,不然不仅开发者闹情绪,用户都快不满足了,后来html5出现以后,这个标准化的工作就提上了日程,谁去做?当然W3C那帮老大哥啊,凡是和www有关的草案,正式标准都是得那发话。
所以众望所归,这个XMLHttpRequest的标准草案在2008年落成,因为增加了许多新的技能,所以叫XMLHttpRequest有点赶不上时代潮流了,叫XMLHttpRequest plus?这个名字有点apple,还是叫XMLHttpRequest level2吧。
到底增加了哪些功能了呢?那先研究下XMLHttpRequest level1基础?那还废什么话直接捋袖子干~
在控制台吧XMLHttpRequest打出来会发现他是一个构造函数,是一个可以继承的类,要使用其上的接口方法属性需要实例化这个方法。
新建一个XMLHttpRequest的实例

1
var xhr = new XMLHttpRequest();

向服务端发送接受数据的请求

1
2
xhr.open(METHOD, URL);
xhr.send(BODY);

服务端主机做出返回要找个事件onreadystatechange监听啊,不仅要监听还要做出反应(回调)

1
xhr.onreadystatechange = callback;

我这个人喜欢总结,喜欢举一反三,你光秃秃给我看XMLHttpRequest这个对象上的几个属性方法,真的能憋死我,就算我去控制台打印调试,我也得一个不落的都给总结了,所以新老版本的XMLHttpRequest属性方法事件都在后面躺着呢,以后记性不好也可以参考参考,不然这日子没法过。

XMLHttpRequest这样看没毛病啊? 谁说他有毛病了,你能说当年的”286”有毛病么?不能,时代在发展,人类在进步,不要嫌弃为我们做过贡献的革命好同志。只是我与XMLHttpRequest不相见已二余年,到现在我忘不掉的还是那个夜晚,从二进制坑里爬不出来我的背影。

  • 只支持文本数据的传送,无法用来读取和上传二进制文件。
  • 传送和接收数据时,没有进度信息,只能提示有没有完成。
  • 受到”同域限制”,只能向同一域名的服务器请求数据

XMLHttpRequest2

最后一条可以说比较过分了,你让我跨域的咋办,jsonp? 那我不用get呢,iframe? 我想静静,不知道她想我么。
所以!! 新一代的XMLHttpRequest出现了,来数一数哪些东西可以让你爬出坑。

增加了timeout属性,可以设置HTTP请求的时限,超时直接处理。
1
2
xhr.timeout =timeout;
xhr.ontimeout = callback;
HTML5新增了一个FormData对象,可以模拟表单,直接传送这个FormData对象,与提交网页表单的效果完全一样
1
2
3
var formData = new FormData();// 新建一个FormData对象
formData.append('username', '张三');// 添加一个额外表单项
xhr.send(formData);
FormData对象也可以用来对页面上现有的 HTMLFormElement 进行初始化。
1
2
3
var form = document.getElementById(‘myform');
// 获取网页表单的值
var formData = new FormData(form);
新版XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件
跨域资源共享(CORS)

可以向不同域名的服务器发出HTTP请求 这叫做”跨域资源共享”(Cross-origin resource sharing,简称CORS)
使用”跨域资源共享”的前提,是浏览器必须支持这个功能,而且服务器端必须同意这种”跨域

接收二进制数据
1. 旧做法 ,改写MIMEType ,详细的有兴趣自己查

较老的做法是改写数据的MIMEType,将服务器返回的二进制数据伪装成文本数据,并且告诉浏览器这是用户自定义的字符集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
// Hack to pass bytes through unprocessed.
xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.onreadystatechange = function(e) {
if (this.readyState == 4 && this.status == 200) {
var binStr = this.responseText;
for (var i = 0, len = binStr.length; i < len; ++i) {
var c = binStr.charCodeAt(i);
//String.fromCharCode(c & 0xff);
var byte = c & 0xff; // byte at offset i
}
}
};
xhr.send();

2.responseType属性
1
2
3
4
5
6
//把responseType设为blob,表示服务器传回的是二进制对象。
var xhr = new XMLHttpRequest();
xhr.open('GET', ‘/path/to/image.png');
xhr.responseType = ‘blob';
//接收数据的时候,用浏览器自带的Blob对象即可。
var blob = new Blob([xhr.response], {type: ‘image/png'});
事件 on+

onprogress:传送数据的时候,返回进度信息调用方式xhr.upload.onprogress
onload:传输成功完成。
onabort:传输被用户取消。
onerror:传输中出现错误。
onloadstart:传输开始。
onloadEnd:传输结束,但是不知道成功还是失败。

1
2
3
4
5
6
7
8
9
10
11
<progress min="0" max="100" value="0">0% complete</progress>
<script>
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
progressBar.textContent = progressBar.value;
}
};
xhr.onload=fn;
//xhr.addEventLisetener("load",fn);
</script>

XMLHttpRequest api

属性

readyState
0 表示初始化状态,XMLHttpRequest对象已经创建或者abort()重置
1 表示open()方法已经调用,但是未send(),请求并没有被发送
2 表示send()方法已经调用,http请求到达服务器,未收到响应
3 所有的响应头都已收到,响应体开始接收但未完成
4 http响应已经完全接收
每次这个属性值增加的时候,都会触发onreadystatechange()事件句柄

status
由服务器返回的 HTTP 状态代码,如 200 表示成功,而 404 表示 “Not Found” 错误。==当readyState小于 3 的时候读取这一属性会导致一个异常==。

statusText
这个属性用名称而不是数字指定了请求的 HTTP的状态代码。也就是说,当状态为 200 的时候它是 “OK”,当状态为 404 的时候它是 “Not Found”。和 status 属性一样,==当 readyState 小于 3 的时候读取这一属性会导致一个异常。==

responseText
目前为止为服务器接收到的响应体(不包括头部),或者如果还没有接收到数据的话,就是空字符串。
如果 readyState 小于 3,这个属性就是一个空字符串。当 readyState 为 3,这个属性返回目前已经接收的响应部分。如果 readyState 为 4,这个属性保存了完整的响应体。
如果响应包含了为响应体指定字符编码的头部,就使用该编码。否则,假定使用 Unicode UTF-8。

responseXML
对请求的响应,解析为 XML 并作为 Document 对象返回。

response
返回 responseType 设置过的格式的数据

responseType
返回什么格式的数据 ==[text,arraybuffer,blob,document] 默认text==

事件

onreadystatechange
每次 readyState 属性改变的时候调用的事件句柄函数。当 readyState 为 3 时,它也可能调用多次。

方法

abort()
取消当前响应,关闭连接并且结束任何未决的网络活动。
这个方法把 XMLHttpRequest 对象重置为 readyState 为0的状态,并且取消所有未决的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法。

getAllResponseHeaders()
把 HTTP 响应头部作为未解析的字符串返回。
如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 “\r\n” 隔开。

getResponseHeader()
返回指定的 HTTP 响应头部的值。
其参数是要返回的 HTTP响应头部的名称。可以使用任何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。
该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyState 小于 3 则为空字符串。
如果接收到多个有指定名称的头部,这个头部的值被连接起来并返回,使用逗号和空格分隔开各个头部的值。

open(method, url, async, username, password)
初始化 HTTP 请求参数,例如 URL 和 HTTP 方法,但是并不发送请求。

send(body)
发送 HTTP 请求,使用传递给 open() 方法的参数,以及传递给该方法的可选请求体。

setRequestHeader(name, value)
name 参数是要设置的头部的名称。这个参数不应该包括空白、冒号或换行。
value 参数是头部的值。这个参数不应该包括换行向一个打开但未发送的请求设置或添加一个 HTTP 请求。

说明
setRequestHeader() 方法指定了一个 HTTP 请求的头部,它应该包含在通过后续 send() 调用而发布的请求中。这个方法只有当 readyState 为 1 的时候才能调用,例如,在调用了open() 之后,但在调用 send() 之前。
如果带有指定名称的头部已经被指定了,这个头部的新值就是:之前指定的值,加上逗号、空白以及这个调用指定的值。
如果 open() 调用指定了认证资格,XMLHttpRequest 自动发送一个适当的 Authorization 请求头部。但是,你可以使用 setRequestHeader() 来添加这个头部。类似地,如果 Web 服务器已经保存了和传递给open() 的 URL 相关联的cookie,适当的 CookieCookie2 头部也自动地包含到请求中。可以通过调用 setRequestHeader()来把这些 cookie 添加到头部。XMLHttpRequest 也可以为 User-Agent 头部提供一个默认值。如果它这么做,你为该头部指定的任何值都会添加到这个默认值后面。
有些请求头部由 XMLHttpRequest 自动设置而不是由这个方法设置,以符合 HTTP 协议。这包括如下和代理相关的头部:
Host
Connection
Keep-Alive
Accept-charset
Accept-Encoding
If-Modified-Since
If-None-Match
If-Range
Range

欢迎交流转载请注明出处