【笔记】XMLHttpRequest学习笔记

前言

XMLHttpRequest(XHR)学习笔记

发送请求

xhr.readyState:XHR状态码

0XMLHttpRequest.UNSENT:未执行open函数
1XMLHttpRequest.OPENED:已执行open函数,未执行send函数
2XMLHttpRequest.HEADERS_RECEIVED:已执行send函数
3XMLHttpRequest.LOADING:正在接收服务器响应的数据
4XMLHttpRequest.DONE:完成接收服务器响应的数据

xhr.status:HTTP响应状态码

200:请求成功

xhr.statusText:HTTP响应状态文本

"OK":请求成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 创建对象
const xhr = new XMLHttpRequest();

// 定义回调函数
xhr.onreadystatechange = function () {
if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200 && xhr.statusText == "OK") {
// 获取响应数据
console.log(xhr.response);
}
}

// 初始化HTTP请求
xhr.open("GET", "http://127.0.0.1:80/api");

// 发送请求
xhr.send(null);

XHR生命周期回调函数

XHR状态发生改变

  • 每当XHR状态发生改变时都会触发
1
xhr.onreadystatechange = function () {}

XHR请求开始

1
xhr.onloadstart = function () {}

XHR请求进行中

  • 每当有数据包接收时都会触发
1
xhr.onprogress = function () {}

XHR请求成功

  • XHR请求成功并获得完整响应内容后触发
1
xhr.onload = function () {}

XHR请求失败

  • XHR请求失败时触发,不会捕获诸如404之类的错误
1
xhr.onerror = function () {}

XHR请求超时

1
xhr.ontimeout = function () {}

XHR请求被手动取消

1
xhr.onabort = function () {}

XHR请求结束

  • onload()onerror()abort()ontimeout()之后触发
1
xhr.onloadend = function () {}

解析响应数据

根据responseType自动解析响应数据

1
2
3
xhr.onload = function () {
xhr.response;
}

以文本格式解析响应数据

1
2
3
xhr.onload = function () {
xhr.responseText;
}

以XML格式解析响应数据

1
2
3
xhr.onload = function () {
xhr.responseXML;
}

初始化HTTP请求

第一个参数:定义请求方法
第二个参数:定义请求URL

1
xhr.open("GET", "http://127.0.0.1:80/api");

第三个参数:定义是否是异步请求

true:缺省值,异步请求
false:同步请求

1
xhr.open("GET", "http://127.0.0.1:80/api", true);

第四个参数:定义用于认证HTTP请求的用户名
第五个参数:定义用于认证HTTP请求的密码

1
xhr.open("GET", "http://127.0.0.1:80/api", true, "<username>", "<password>");

设置请求头

1
xhr.setRequestHeader("key", "value");

定义响应数据格式

  • 在通过xhr.response获取响应数据时,根据定义的响应数据格式进行解析

text:缺省值,文本格式
json:JSON格式
xml:XML格式

1
xhr.responseType = "json";

设置超时时间

  • 超时时间缺省值为0,表示永不超时
1
xhr.timeout = 0;

发送请求

无请求体

1
xhr.send(null);

有请求体

1
xhr.send("key=value");

手动取消请求

1
xhr.abort();

发送GET请求

传递query参数

1
2
3
4
5
6
7
const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("GET", `http://127.0.0.1:80/api?key=value`, true);
xhr.responseType = "json";
xhr.send();

发送POST请求

传递FormData参数

手动拼接字符串

1
2
3
4
5
6
7
8
const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.responseType = "json";
xhr.send(`key=value`);

创建FormData对象

1
2
3
4
5
6
7
8
9
10
11
const formData = new FormData();
formData.append("key", "value");

const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.responseType = "json";
xhr.send(formData);

通过Form表单元素创建FormData对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<form id="app">
...
</form>

<script>
const formElement = document.getElementById("app");
const formData = new FormData(formElement);

const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.responseType = "json";
xhr.send(formData);
</script>

传递JSON参数

手动拼接字符串

1
2
3
4
5
6
7
8
const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.responseType = "json";
xhr.send(`{ key: "value" }`);

通过JS对象转换为JSON格式字符串

1
2
3
4
5
6
7
8
9
10
11
12
const jsonData = JSON.stringify({
key: "value"
});

const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.responseType = "json";
xhr.send(jsonData);

文件上传

上传单图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<form id="app">
<input type="file" id="file">
</form>

<script>
const fileElement = document.getElementById("file");
const formData = new FormData();
formData.append("key", fileElement.files[0]);

const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.responseType = "json";
xhr.send(jsonData);
</script>

上传多图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<form id="app">
<input type="file" id="file">
</form>

<script>
const fileElement = document.getElementById("file");
const formData = new FormData();
formData.append("key", fileElement.files);

const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.responseType = "json";
xhr.send(jsonData);
</script>

监听上传进度

  • 通过xhr.onprogress()监听上传进度

event.loaded:当前上传进度
event.total:总进度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<form id="app">
<input type="file" id="file">
</form>

<script>
const fileElement = document.getElementById("file");
const formData = new FormData();
formData.append("key", fileElement.files);

const xhr = new XMLHttpRequest();
xhr.onload = function () {
...
};
xhr.onprogress = function (event) {
console.log(event.loaded);
console.log(event.total);
};
xhr.open("POST", "http://127.0.0.1:80/api", true);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.responseType = "json";
xhr.send(jsonData);
</script>

关于浏览器兼容问题的解决

定义createXmlHttpRequest函数

  • 定义createXmlHttpRequest函数,用于兼容不同浏览器创建XMLHttpRequest对象
1
2
3
4
5
6
7
8
9
10
11
12
13
function createXmlHttpRequest() {
if (window.XMLHttpRequest) {
// 针对谷歌、火狐等主流浏览器
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
// 针对IE5、IE6浏览器
return new ActiveXObject("Microsoft.XMLHTTP");
} else {
// 其他不支持XHR的浏览器
alert("您的浏览器不支持Ajax,请更换浏览器");
return null;
}
}

创建XMLHttpRequest对象

1
const xhr = createXmlHttpRequest();

完成

参考文献

CSDN——Lv547