XMLHttpRequest 说明
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
XMLHttpRequest 对象,主要用于发送http请求给后端
使用方式
1、创建XHR 对象
所有现代浏览器都通过 XMLHttpRequest 构造函数原生支持 XHR 对象
let xhr = new XMLHttpRequest();
2、基本配置
使用 XHR 对象首先要调用 open( )方法,对本次发送的请求进行配置。
调用 open()不会实际发送请求,只是为发送请求做好准备。
xhr.open("get", "example.php", false); // 这行代码就可以向 example.php 发送一个同步的 GET 请求。
这个方法接收 3 个参数:
1、请求类型(”get”、”post”等)
2、请求 URL,
(1)这里的 URL 是相对于代码所在页面的,当然也可以使用绝对 URL
(2)只能访问同源 URL,也就是域名相同、端口相同、协议相同。如果请求的 URL 与发送请求的页面在任何方面有所不同,则会抛出安全错误
3、请求是否异步的布尔值。
3、配置接收服务器响应后执行
通过 onreadystatechange 方法,配置收到服务器响应后要执行的方法,见下面的 6、收到服务器的响应
4、发送给服务器
要发送定义好的请求,必须像下面这样调用 send()方法
xhr.send(null);
send()方法接收一个参数,是作为请求体发送的数据。如果不需要发送请求体,则必须传 null,因为这个参数在某些浏览器中是必需的。
调用 send()之后,请求就会发送到服务器。
如果这个请求是同步的,所以 JavaScript 代码会等待服务器响应之后再继续执行。
5、服务器收到请求并返回数据
6、收到服务器的响应
收到响应后,XHR对象的以下属性会被填充上数据:
responseText:作为响应体返回的文本。
responseXML:如果响应的内容类型是”text/xml”或”application/xml”,那就是包含响应数据的 XML DOM 文档。
status:响应的 HTTP 状态,如成功是200,url地址不存在就是404等。
statusText:响应的 HTTP 状态描述。
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
// 2、如果成功,responseText 或 responseXML(如果内容类型正确)属性中会有内容,此时可以显示响应体responseText
alert(xhr.responseText);
} else {
// 3、如果不成功,检查响应的 HTTP 状态
alert("Request was unsuccessful: " + xhr.status);
}
XHR 对象有一个 readyState 属性,表示当前处在请求/响应过程的哪个阶段。
这个属性有如下可能的值:
0:未初始化(Uninitialized)。尚未调用 open()方法。
1:已打开(Open)。已调用 open()方法,尚未调用 send()方法。
2:已发送(Sent)。已调用 send()方法,尚未收到响应。
3:接收中(Receiving)。已经收到部分响应。
4:完成(Complete)。已经收到所有响应,可以使用了。
每次 readyState 从一个值变成另一个值,都会触发 readystatechange 事件。
可以借此机会检查 readyState 的值。一般来说,我们唯一关心的 readyState 值是 4,表示数据已就绪。
为保证跨浏览器兼容,onreadystatechange 事件处理程序应该在调用 open()之前赋值。
// 1、创建
let xhr = new XMLHttpRequest();
// 2、基本配置
xhr.open("get", "example.txt", true);
// 3、配置接收服务器响应后要执行什么
xhr.onreadystatechange = function() {
// 3.1 检查状态,看是否请求完成
if (xhr.readyState == 4) {
// 3.2 检查请求的状态
// 一般来说,HTTP 状态码为 2xx 表示成功
// 如果 HTTP状态码是 304,则表示资源未修改过,是从浏览器缓存中直接拿取的。当然这也意味着响应有效。
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
// 展示服务器返回的内容
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
// 4、发送
xhr.send(null);
7、取消(可选)
在收到响应之前如果想取消异步请求,可以调用 abort()方法
xhr.abort();
调用这个方法后,XHR 对象会停止触发事件,并阻止访问这个对象上任何与响应相关的属性。
中断请求后,应该取消对 XHR 对象的引用。
由于内存问题,不推荐重用 XHR 对象。
HTTP header 请求头信息
通用信息
(谷歌浏览器按F12可以查看DevTools调试器)
每个 HTTP 请求和响应都会携带一些头部字段,这些字段可能对开发者有用。
XHR 对象会通过一些方法暴露与请求和响应相关的头部字段。
默认情况下,XHR 请求会发送以下头部字段。
accept:浏览器可以处理的内容类型。
accept-charset:浏览器可以显示的字符集。
accept-encoding:浏览器可以处理的压缩编码类型。
accept-language:浏览器使用的语言。
connection:浏览器与服务器的连接类型。
cookie:页面中设置的 Cookie。
host:发送请求的页面所在的域。
referer:发送请求的页面的 URI。注意,这个字段在 HTTP 规范中就拼错了,所以考虑到兼容性也必须将错就错。(正确的拼写应该是 Referrer。)
user-agent:浏览器的用户代理字符串。
设置信息
不同浏览器发送的请求头可能会不一样,但是通用的部分应该都是有的。
如果需要发送额外的请求头部,可以使用 setRequestHeader()方法。
这个方法接收两个参数:头部字段的名称和值。
为保证请求头部被发送,必须在 open()之后、send()之前调用 setRequestHeader()
// 1、创建
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
// 2、准备
xhr.open("get", "example.txt", true);
// 设置自定义头部信息
xhr.setRequestHeader("MyHeader", "MyValue");
// 3、发送
xhr.send(null);
设置请求头的意义,一般有2点:
1、设置 content-type :告诉客户端实际返回的内容的内容类型,这点很重要,会影响到后端服务器怎么去解析你的数据,否则可能会导致后端拿不到数据。
这里设置的内容可以查看:https://www.yuque.com/yejielin/mypn47/lq4be4
一般就是application/json(表示json格式的数据),或者x-www-form-urlencoded (表示是url编码后的数据)等
2、设置 自定义请求头:比如有的后端会规定身份令牌(Token)需要放在请求头里面,而不是放在数据里面进行传输,此时就需要设置请求头。
GET 请求
最常用的请求方法是 GET 请求,用于向服务器查询某些信息。
必要时,需要在 GET 请求的 URL后面添加查询字符串参数。
对 XHR 而言,查询字符串必须正确编码后添加到 URL 后面,然后再传给open()方法。
xhr.open("get", "example.php?name1=value1&name2=value2", true);
// 可以使用以下函数将查询字符串参数添加到现有的 URL 末尾
function addURLParam(url, name, value) {
url += (url.indexOf("?") == -1 ? "?" : "&");
url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
return url;
}
可以使用这个函数构建请求 URL
let url = "example.php";
// 添加参数
url = addURLParam(url, "name", "Nicholas");
url = addURLParam(url, "book", "Professional JavaScript");
// 初始化请求
xhr.open("get", url, false);
POST 请求
第二个最常用的请求是 POST 请求,用于向服务器发送应该保存的数据。
每个 POST 请求都应该在请求体中携带提交的数据,而 GET 请求则不然。
POST 请求的请求体可以包含非常多的数据,而且数据可以是任意格式。
要初始化 POST 请求,open()方法的第一个参数要传”post”,
xhr.open("post", "example.php", true);
xhr.send("要发送的数据")
默认情况下,对服务器而言,POST 请求与提交表单是不一样的。
服务器逻辑需要读取原始 POST数据才能取得浏览器发送的数据。
不过,可以使用 XHR 模拟表单提交。
function submitData() {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("post", "postexample.php", true);
// 1、需要把 Content-Type 头部设置为"application/x-www-formurlencoded",这是提交表单时使用的内容类型
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
let form = document.getElementById("user-info");
// 2、创建对应格式的字符串
xhr.send(serialize(form));
}
POST 请求相比 GET 请求要占用更多资源。从性能方面说,发送相同数量的数据,GET 请求比 POST 请求要快两倍。
=================
第三方库
Axios
原理是使用XMLHttpRequest 对象发送网络请求,在此基础上包装了Promise和一些方法(如拦截请求、拦截响应等),是现代较为流行的网络请求库之一。
以前Vue团队自己也开发了网络请求的库,后来不维护了,而是推荐使用Axios这个库。