XMLHttpRequest的发展历程
XMLHttpRequest一开始只是微软浏览器提供的一个接口,后来各大浏览器纷纷效仿也提供了这个接口,再后来W3C对它进行了标准化,提出了XMLHttpRequest标准。XMLHttpRequest标准又分为Level 1和Level 2。
XMLHttpRequest Level 1主要存在以下缺点:
- 受同源策略的限制,不能发送跨域请求;
- 不能发送二进制文件(如图片、视频、音频等),只能发送纯文本数据;
- 在发送和获取数据的过程中,无法实时获取进度信息,只能判断是否完成;
那么Level 2对Level 1 进行了改进,XMLHttpRequest Level 2中新增了以下功能:
-
可以发送跨域请求,在服务端允许的情况下;
-
支持发送和接收二进制数据;
-
新增formData对象,支持发送表单数据;
-
发送和获取数据时,可以获取进度信息;
-
可以设置请求的超时时间;
细说XMLHttpRequest如何使用
先来看一段使用XMLHttpRequest发送Ajax请求的简单示例代码。
function sendAjax() {
//构造表单数据
var formData = new FormData();
formData.append('username', 'johndoe');
formData.append('id', 123456);
//创建xhr对象
var xhr = new XMLHttpRequest();
//设置xhr请求的超时时间
xhr.timeout = 3000;
//设置响应返回的数据格式
xhr.responseType = "text";
//是否携带cookie
xhr.withCredentials = true
//创建一个 post 请求,采用异步
xhr.open('POST', '/server', true);
//注册相关事件回调处理函数
xhr.onload = function(e) {
if(this.status == 200||this.status == 304){
alert(this.responseText);
}
};
//监听当前请求状态,也可用于获取返回值————————————核心代码
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {//
let a = JSON.parse(xhr.responseText).data
console.log(a)
}
}
//当请求成功完成时触发,此时xhr.readystate=4
xhr.onload = function(e) {
if(request.status == 200) {
console.log(e.target.response)
}
}
//超时触发
xhr.ontimeout = function(e) { ... };
xhr.onerror = function(e) { ... };
//发送数据(发起请求)
xhr.send(formData);
//中止请求
xhr.abort();
}
responseType格式
IE不用考虑了,停止维护了。
容易忽略:用了默认值,返回就是一个字符串,你需要JSON.parse()处理一下
xhr.responseType = ‘blob’ 设置这个的时候,你获取到的就是一个二进制字符串,当后端给你返回图片、文件时候你就得这么处理

send()方法
xhr.send(data)中data参数的数据类型会影响请求头部content-type的默认值:
都说默认值咯,特地指定的话是可以覆盖的
- 如果data是 Document 类型,同时也是HTML
Document类型,则content-type默认值为text/html;charset=UTF-8;否则为application/xml;charset=UTF-8; - 如果data是 DOMString 类型,content-type默认值为text/plain;charset=UTF-8;
- 如果data是 FormData 类型,content-type默认值为multipart/form-data;
boundary=[xxx] - 如果data是其他类型,则不会设置content-type的默认值
只能在post情况下,send()才带参数,get不传或者null
可以传formdata
var formData = new FormData();
formData.append('levelName', '张三2');
formData.append('courseLayer', 'S1C')
xhr.send(formData)
但是可以被这种写法代替,但是当你使用原生时候,formdata就formdata写法比较好,别瞎死烂代码
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send('levelName=996&courseLayer=336')
可以传一个字符串
注意是一个,没有为什么,所以才有二次封装,我们可以把JSON序列化传出去
:基本就只使用上面这两种

事件触发顺序
当请求一切正常时,相关的事件触发顺序如下:
-
触发xhr.onreadystatechange(之后每次readyState变化时,都会触发一次)
//上传阶段开始: -
触发xhr.onloadstart
-
触发xhr.upload.onloadstart
-
触发xhr.upload.onprogress
-
触发xhr.upload.onload
-
触发xhr.upload.onloadend
//上传结束,下载阶段开始:
-
触发xhr.onprogress
-
触发xhr.onload
-
触发xhr.onloadend
onreadystatechange方法
状态更改时候就会触发
坑
- ,open()第三个参数为false时候是同步请求,当xhr为一个同步请求时,xhr.timeout必须置为0,否则会抛错。尽量还是别用同步,还有坑
- 文档链接

1347

被折叠的 条评论
为什么被折叠?



