1.XMLHttpRequest 对象是什么?
浏览器与服务器之间,采用 HTTP 协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出 HTTP 请求。
1999年,微软公司发布 IE 浏览器5.0版,第一次引入新功能:允许 JavaScript 脚本向服务器发起 HTTP 请求。这个功能当时并没有引起注意,直到2004年 Gmail 发布和2005年 Google Map 发布,才引起广泛重视。2005年2月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML
的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词,也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。W3C 也在2006年发布了它的国际标准。
具体来说,AJAX 包括以下几个步骤。
- 创建 XMLHttpRequest 实例
- 发出 HTTP 请求
- 接收服务器传回的数据
- 更新网页数据
总结一下就是为了实现网页在不刷新的情况下自动更新网页页面内的数据,就需要我们从后端获取数据来显示到前端页面上。那么前端负责完成通信建立、数据接收、数据显示的就是javascript
的工作了。那么对于前端JS处理HTTP通信的行为我们称之为AJAX(异步JavaScript和XML)。也可以叫它阿贾克斯。
注意,这里的XML是作为通信模板来使用的,用于在不同语言的后端程序和前端进行信息交互时提供一个统一的模板。现在已经被JSON格式替换掉了,但是其还是沿用XML这个名称。故AXJX现在被用来表示一种行为。
最后就来解释XMLhttprequest对象:XMLHttpRequest
对象是 AJAX 的主要接口,用于浏览器与服务器之间的通信。尽管名字里面有XML
和Http
,它实际上可以使用多种协议(比如file
或ftp
),发送任何格式的数据(包括字符串和二进制)。
1.1 初次尝试AJAX
本小节我们尝试运行一段ajax脚本来体验一下在前端用JS构建HTTP通信的感觉。这里注意AJAX 只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求,如果发出跨域请求,就会报错。AJAX仅适用于同源通信。
先新建一个网页01.html,内部包含进去一个js文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>源页面---</h1>
</body>
<script src="./01.js"></script>
</html>
在新建第二个网页02.html,作为我们AJAX访问的目标
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>被请求网页:"hello world"</h1>
</body>
</html>
此时将下面的JS代码保存到01.js文件中去:
//XMLHttpRequest本身是一个构造函数,可以使用new命令生成实例。它没有任何参数。
var xhr = new XMLHttpRequest();
//使用事件监听属性监听请求的结果,并在函数内写上对其的操作
xhr.onreadystatechange = function(){
// 通信成功时,状态值为4
if (xhr.readyState === 4){
//判断状态码是否为200 OK,否则抛出错误
if (xhr.status === 200){
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
}
};
//使用事件监听属性监听error事件,指定状态码错误回显
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
//调用实例的open()方法,进行get请求的参数设定,其中第三个请求true的意思是异步进行请求
xhr.open('GET', './03.html', true);
//最后使用send()方法实际发出请求
xhr.send(null);
测试访问效果:
可以看到,在控制台中有通过AJAX访问目标页面所获的的返回结果。证明此次的AJAX通信时成功的。当我们修改JS中的请求页面为03.html时就会回显出404的状态码。
那么接下来,我们就要深入的去了解一下关于xmlhttprequest的用法了。
1.2 一些不清楚的概念
1.2.1 异步请求与同步请求的区别
ajax异步请求:异步请求就当发出请求的同时,浏览器可以继续做任何事,Ajax发送请求并不会影响页面的加载与用户的操作,相当于是在两条线上,各走各的,互不影响。一般默认值为true。异步请求可以完全不影响用户的体验效果,无论请求的时间长或者短,用户都在专心的操作页面的其他内容,并不会有等待的感觉。
ajax同步请求:同步请求即是当前发出请求后,浏览器什么都不能做,必须得等到请求完成返回数据之后,才会执行后续的代码,相当于是排队,也就是说,当JS代码加载到当前ajax的时候会把页面里所有的代码停止加载,页面处于一个假死状态,当这个ajax执行完毕后才会继续运行其他代码页面解除假死状态(即当ajax返回数据后,才执行后面的function)。
也可以理解为假设我们需要烧水煮饺子,那么在同步传输的情景下,我们就必须依次完成烧水、包饺子、煮饺子、吃饺子这四件事。那么在异步请求下,我们就可以烧水和包饺子同时进行,开辟两条时间线去完成这个事情可以一定程度上节省时间。
1.2.2 一捏捏面向对象的知识
1.对象是什么?
(1)对象是单个实物的抽象。
一本书、一辆汽车、一个人都可以是对象,一个数据库、一张网页、一个远程服务器连接也可以是对象。当实物被抽象成对象,实物之间的关系就变成了对象之间的关系,从而就可以模拟现实情况,针对对象进行编程。
(2)对象是一个容器,封装了属性(property)和方法(method)。
属性是对象的状态,方法是对象的行为(完成某种任务)。比如,我们可以把动物抽象为animal
对象,使用“属性”记录具体是哪一种动物,使用“方法”表示动物的某种行为(奔跑、捕猎、休息等等)。
即就是说,对于一个对象来说会有两类重要的指标或者说是描述的要点,就是对象的属性与方法。属性是描述的参数,方法是这个对象可以进行的一些行为。
2.构造函数是啥?
面向对象编程的第一步,就是要生成对象。前面说过,对象是单个实物的抽象。通常需要一个模板,表示某一类实物的共同特征,然后对象根据这个模板生成。
典型的面向对象编程语言(比如 C++ 和 Java),都有“类”(class)这个概念。所谓“类”就是对象的模板,对象就是“类”的实例。但是,JavaScript 语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)。
JavaScript 语言使用构造函数(constructor)作为对象的模板。所谓”构造函数”,就是专门用来生成实例对象的函数。它就是对象的模板,描述实例对象的基本结构。一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。
构造函数相当于是一个特殊的函数,不过其有自己的特征以及用法。在创建对象时使用new命令进行创建。构造函数名字的第一个字母通常大写。
看到这里,大概就明白了,要学习XMLhttprequest对象,就是要对这个对象创建的实例所能使用的属性、以及方法进行一个比较系统的了解。趁热打铁,先来看看XMLHttpRequest
的实例属性
2.XMLHttpRequest 的实例属性
2.1 readyState与onreadystatechange
XMLHttpRequest.readyState
返回一个整数,表示实例对象的当前状态。该属性只读。它可能返回以下值。
- 0、表示 XMLHttpRequest 实例已经生成,但是实例的
open()
方法还没有被调用。 - 1,表示
open()
方法已经调用,但是实例的send()
方法还没有调用,仍然可以使用实例的setRequestHeader()
方法,设定 HTTP 请求的头信息。 - 2,表示实例的
send()
方法已经调用,并且服务器返回的头信息和状态码已经收到。 - 3,表示正在接收服务器传来的数据体(body 部分)。这时,如果实例的
responseType
属性等于text
或者空字符串,responseText
属性就会包含已经收到的部分信息。 - 4,表示服务器返回的数据已经完全接收,或者本次接收已经失败。
通信过程中,每当实例对象发生状态变化,它的readyState
属性的值就会改变。这个值每一次变化,都会触发readyStateChange
事件。
对于XMLHttpRequest.onreadystatechange
属性指向一个监听函数。它的作用是当readystatechange
事件发生时(实例的readyState
属性变化),就会执行依次这个函数内的操作。另外,如果使用实例的abort()
方法,终止 XMLHttpRequest 请求,也会造成readyState
属性变化,导致调用XMLHttpRequest.onreadystatechange
属性。
例1:验证每一次readystate变化会触发readyStateChange
事件。
//XMLHttpRequest本身是一个构造函数,可以使用new命令生成实例。它没有任何参数。
var xhr = new XMLHttpRequest();
console.log(xhr.readyState);
//使用事件监听属性监听请求的结果,并在函数内打印出对应的阶段
xhr.onreadystatechange = function(){
// 通信成功时,状态值为4
if (xhr.readyState === 0){
console.log("实例已创建");
console.log(xhr.readyState);
}
if (xhr.readyState === 1){
console.log("已经调用open()方法");
console.log(xhr.readyState);
}
if (xhr.readyState === 2){
console.log("已经调用send()方法,收到信息头部");
console.log(xhr.readyState);
console.log(xhr.getAllResponseHeaders());
}
if (xhr.readyState === 3){
console.log("正在接收数据体");
console.log(xhr.readyState);
}
if (xhr.readyState === 4){
console.log("请求接收完毕");
console.log(xhr.readyState);
console.log(xhr.responseText);
}
};
//调用实例的open()方法,进行get请求的参数设定,其中第三个请求true的意思是异步进行请求
xhr.open('get', 'http://127.0.0.1/secbasic/02.html', true);
//最后使用send()方法实际发出请求
xhr.send(null);
2.2 XMLHttpRequest.response
XMLHttpRequest.response
属性表示服务器返回的数据体(即 HTTP 回应的 body 部分)。它可能是任何数据类型,比如字符串、对象、二进制对象等等,具体的类型由XMLHttpRequest.responseType
属性决定。该属性只读。
如果本次请求没有成功或者数据不完整,该属性等于null
。但是,如果responseType
属性等于text
或空字符串,在请求没有结束之前(readyState
等于3的阶段),response
属性包含服务器已经返回的部分数据。
当然这里的部分数据是说延迟较大,请求内容也比较大的时候才会出现这样的部分显示。本地的此时结果通常在这个阶段就已经接受到说有所需的信息了。
2.3 XMLHttpRequest.responseType
XMLHttpRequest.responseType
属性是一个字符串,表示服务器返回数据的类型。这个属性是可写的,可以在调用open()
方法之后、调用send()
方法之前,设置这个属性的值,告诉浏览器如何解读返回的数据。如果responseType
设为空字符串,就等同于默认值text
。
XMLHttpRequest.responseType
属性可以等于以下值。
- “”(空字符串):等同于
text
,表示服务器返回文本数据。 - “arraybuffer”:ArrayBuffer 对象,表示服务器返回二进制数组。
- “blob”:Blob 对象,表示服务器返回二进制对象。
- “document”:Document 对象,表示服务器返回一个文档对象。
- “json”:JSON 对象。
- “text”:字符串。
上面几种类型之中,text
类型适合大多数情况,而且直接处理文本也比较方便。document
类型适合返回 HTML / XML 文档的情况,这意味着,对于那些打开 CORS 的网站,可以直接用 Ajax 抓取网页,然后不用解析 HTML 字符串,直接对抓取回来的数据进行 DOM 操作。blob
类型适合读取二进制数据,比如图片文件。
示例1:JSON对象返回参数接收
//后端php页面--- 01.php
<?
//创建数组存储数据
$arr = array('name' => 'batman','age' => '18','money' => '?????');
//调用json_ecode函数将返回值json化
echo json_encode($arr);
//测试JS --- 01.js
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1/secbasic/01.php', true);
xhr.responseType = 'json';
xhr.send(null);
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
//这里不可以在使用固定格式的responsetext会报出类型不匹配的错误
console.log(xhr.response);
}
else{
console.error(xhr.status);
}
};
示例2:AJAX请求图片文件
var xhr = new XMLHttpRequest();
xhr.open('GET', './01.png', true);
xhr.responseType = 'blob';
xhr.send();
xhr.onload = function(e) {
if (this.status === 200) {
//var blob = new Blob([xhr.response], {type: 'image/png'});
// 或者
var blob = xhr.response;
console.log(blob);
}
};
2.4 XMLHttpRequest.responseText
XMLHttpRequest.responseText
属性返回从服务器接收到的字符串,该属性为只读。只有 HTTP 请求完成接收以后,该属性才会包含完整的数据。
示例:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1/secbasic/02.html', true);
xhr.responseType = 'text';
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
//判断状态4,状态码为200时日志打印出此属性
console.log(xhr.responseText);
}
};
xhr.send(null);
2.5 XMLHttpRequest.responseURL
XMLHttpRequest.responseURL
属性是字符串,表示发送数据的服务器的网址。
注意,这个属性的值与open()
方法指定的请求网址不一定相同。如果服务器端发生跳转,这个属性返回最后实际返回数据的网址。另外,如果原始 URL 包括锚点(fragment),该属性会把锚点剥离。
示例:返回重定向后发送信息的网址
01.js的代码内容:
//这里使用之前的一段代码,稍加修改
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1/secbasic/02.php', true);
xhr.responseType = 'json';
xhr.send(null);
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
//这里不可以在使用固定格式的responsetext会报出类型不匹配的错误
console.log(xhr.response);
}
else{
console.error(xhr.status);
}
};
01.php和02.php的内容:
//php --- 01.php
<?
//创建数组存储数据
$arr = array('name' => 'batman','age' => '18','money' => '?????');
//调用json_ecode函数将返回值json化
echo json_encode($arr);
//php --- 02.php
<?php
header("location: ./01.php", true, 302);
2.6 XMLHttpRequest.status与statusText
XMLHttpRequest.status
属性返回一个整数,表示服务器回应的 HTTP 状态码。一般来说,如果通信成功的话,这个状态码是200;如果服务器没有返回状态码,那么这个属性默认是200。请求发出之前,该属性为0
。该属性只读。
- 200, OK,访问正常
- 301, Moved Permanently,永久移动
- 302, Moved temporarily,暂时移动
- 304, Not Modified,未修改
- 307, Temporary Redirect,暂时重定向
- 401, Unauthorized,未授权
- 403, Forbidden,禁止访问
- 404, Not Found,未发现指定网址
- 500, Internal Server Error,服务器发生错误
基本上,只有2xx和304的状态码,表示服务器返回是正常状态。
XMLHttpRequest.statusText
属性返回一个字符串,表示服务器发送的状态提示。不同于status
属性,该属性包含整个状态信息,比如“OK”和“Not Found”。在请求发送之前(即调用open()
方法之前),该属性的值是空字符串;如果服务器没有返回状态提示,该属性的值默认为“OK”。该属性为只读属性。
示例:
var xhr = new XMLHttpRequest();
console.log("调用open()函数之前的xhr.statusText:");
console.log(xhr.statusText);
xhr.open('GET', 'http://127.0.0.1/secbasic/02.html', true);
xhr.responseType = 'json';
xhr.send(null);
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
//这里不可以在使用固定格式的responsetext会报出类型不匹配的错误
console.log("xhr.status:");
console.log(xhr.status);
console.log("xhr.statusText:");
console.log(xhr.statusText);
}
};
2.7 XMLHttpRequest.timeout与ontimeout
XMLHttpRequest.timeout
属性返回一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。如果该属性等于0,就表示没有时间限制。
XMLHttpRequestEventTarget.ontimeout
属性用于设置一个监听函数,如果发生 timeout 事件,就会执行这个监听函数。
示例:
var xhr = new XMLHttpRequest();
//访问目标URL
var url = 'https://www.google.com';
xhr.ontimeout = function () {
console.error('The request for ' + url + ' timed out.');
};
xhr.onload = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// 处理服务器返回的数据
console.info(xhr.response);
} else {
console.error(xhr.statusText);
}
}
};
xhr.open('GET', url, true);
// 指定 10 秒钟超时
xhr.timeout = 3 * 1000;
xhr.send(null);
2.8 事件监听属性
XMLHttpRequest 对象可以对以下事件指定监听函数。
- XMLHttpRequest.onloadstart:loadstart 事件(HTTP 请求发出)的监听函数
- XMLHttpRequest.onprogress:progress事件(正在发送和加载数据)的监听函数
- XMLHttpRequest.onabort:abort 事件(请求中止,比如用户调用了
abort()
方法)的监听函数 - XMLHttpRequest.onerror:error 事件(请求失败)的监听函数
- XMLHttpRequest.onload:load 事件(请求成功完成)的监听函数
- XMLHttpRequest.ontimeout:timeout 事件(用户指定的时限超过了,请求还未完成)的监听函数
- XMLHttpRequest.onloadend:loadend 事件(请求完成,不管成功或失败)的监听函数
progress
事件的监听函数有一个事件对象参数,该对象有三个属性:loaded
属性返回已经传输的数据量,total
属性返回总的数据量,lengthComputable
属性返回一个布尔值,表示加载的进度是否可以计算。所有这些监听函数里面,只有progress
事件的监听函数有参数,其他函数都没有参数。
注意,如果发生网络错误(比如服务器无法连通),onerror
事件无法获取报错信息。也就是说,可能没有错误对象,所以这样只能显示报错的提示。
其中,常用的事件有onload、ontimeout、onerror等。
示例:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1/secbasic/02.html', true);
// xhr.open('GET', 'http://www.baidu.com', true);
xhr.onload = function() {
var responseText = xhr.responseText;
console.log(responseText);
// process the response.
};
xhr.onabort = function () {
console.log('The request was aborted');
};
xhr.onprogress = function (event) {
console.log(event.loaded);
console.log(event.total);
};
xhr.onerror = function() {
console.log('There was an error!');
};
xhr.send(null);
尝试跨域请求百度的URL,返回了一个错误:
添加人为的中断通信:
测试正常的请求:
2.9 XMLHttpRequest.upload
XMLHttpRequest 不仅可以发送请求,还可以发送文件,这就是 AJAX 文件上传。发送文件以后,通过XMLHttpRequest.upload
属性可以得到一个对象,通过观察这个对象,可以得知上传的进展。主要方法就是监听这个对象的各种事件:loadstart、loadend、load、abort、error、progress、timeout。
示例:
在01.html页面上插入元素
<progress min="0" max="100" value="0">0% complete</progress>
修改01.js的内容:
//定义上传函数,参数为bloborfile,函数内进行文件上传的操作
function upload(blobOrFile) {
var xhr = new XMLHttpRequest();
xhr.open('POST', './01.php', true);
xhr.onload = function (e) {};
//抓取特定标签
var progressBar = document.querySelector('progress');
//监听上传进度
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
progressBar.value = (e.loaded / e.total) * 100;
// 兼容不支持 <progress> 元素的老式浏览器
progressBar.textContent = progressBar.value;
}
};
xhr.send(blobOrFile);
}
//调用上传函数
upload(new Blob(['hello world'], {type: 'text/plain'}));
我们可以看到小蓝条sou的一下就满了。可以用来动态显示上传进度。
3.XMLHttpRequest 的实例方法
3.1 XMLHttpRequest.open()
XMLHttpRequest.open()
方法用于指定 HTTP 请求的参数,或者说初始化 XMLHttpRequest 实例对象。它一共可以接受五个参数。
void open(
string method,
string url,
optional boolean async,
optional string user,
optional string password
);
method
:表示 HTTP 动词方法,比如GET
、POST
、PUT
、DELETE
、HEAD
等。url
: 表示请求发送目标 URL。async
: 布尔值,表示请求是否为异步,默认为true
。如果设为false
,则send()
方法只有等到收到服务器返回了结果,才会进行下一步操作。该参数可选。由于同步 AJAX 请求会造成浏览器失去响应,许多浏览器已经禁止在主线程使用,只允许 Worker 里面使用。所以,这个参数轻易不应该设为false
。user
:表示用于认证的用户名,默认为空字符串。该参数可选。password
:表示用于认证的密码,默认为空字符串。该参数可选。
注意,如果对使用过open()
方法的 AJAX 请求,再次使用这个方法,等同于调用abort()
,即终止请求。
3.2 XMLHttpRequest.send()
XMLHttpRequest.send()
方法用于实际发出 HTTP 请求。它的参数是可选的,如果不带参数,就表示 HTTP 请求只有一个 URL,没有数据体,典型例子就是 GET 请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是 POST 请求。
示例1:get请求的例子
var xhr = new XMLHttpRequest();
//GET请求的参数,作为查询字符串附加在 URL 后面。
xhr.open('GET',
'http://www.example.com/?id=' + encodeURIComponent(id),
true
);
xhr.send(null);
示例2:POST请求发送
//php --- 01.php 直接打印出POST接到的数据
<?var_dump($_POST);
//01.js
var xhr = new XMLHttpRequest();
var username = "batman";
var password = "123456";
//拼接请求体数据
var data = 'username='
+ encodeURIComponent(username)
+ '&password='
+ encodeURIComponent(password);
xhr.open('POST', 'http://127.0.0.1/secbasic/01.php', true);
//设置请求头的content-type字段保持与请求体数据类型的一致性
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(data);
xhr.onload = function() {
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.response);
}
};
3.3 setRequestHeader()
XMLHttpRequest.setRequestHeader()
方法用于设置浏览器发送的 HTTP 请求的头信息。该方法必须在open()
之后、send()
之前调用。如果该方法多次调用,设定同一个字段,则每一次调用的值会被合并成一个单一的值发送。
该方法接受两个参数。第一个参数是字符串,表示头信息的字段名,第二个参数是字段值。
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Content-Length', JSON.stringify(data).length);
xhr.send(JSON.stringify(data));
上面代码首先设置头信息Content-Type
,表示发送 JSON 格式的数据;然后设置Content-Length
,表示数据长度;最后发送 JSON 数据。
3.4 overrideMimeType()
XMLHttpRequest.overrideMimeType()
方法用来指定 MIME 类型,覆盖服务器返回的真正的 MIME 类型,从而让浏览器进行不一样的处理。举例来说,服务器返回的数据类型是text/xml
,由于种种原因浏览器解析不成功报错,这时就拿不到数据了。为了拿到原始数据,我们可以把 MIME 类型改成text/plain
,这样浏览器就不会去自动解析,从而我们就可以拿到原始文本了。
xhr.overrideMimeType('text/plain')
修改服务器返回的数据类型,不是正常情况下应该采取的方法。如果希望服务器返回指定的数据类型,可以用responseType
属性告诉服务器使用何种解析模式。只有在服务器无法返回某种数据类型时,才使用overrideMimeType()
方法。
3.5 getResponseHeader()
XMLHttpRequest.getResponseHeader()
方法返回 HTTP 头信息指定字段的值,如果还没有收到服务器回应或者指定字段不存在,返回null
。该方法的参数不区分大小写。
function getHeaderTime() {
console.log(this.getResponseHeader("Last-Modified"));
}
var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'aimurl');
xhr.onload = getHeaderTime;
xhr.send();
如果有多个字段同名,它们的值会被连接为一个字符串,每个字段之间使用“逗号+空格”分隔。
3.6 getAllResponseHeaders()
XMLHttpRequest.getAllResponseHeaders()
方法返回一个字符串,表示服务器发来的所有 HTTP 头信息。格式为字符串,每个头信息之间使用CRLF
分隔(回车+换行),如果没有收到服务器回应,该属性为null
。如果发生网络错误,该属性为空字符串。
示例:测试返回的请求头信息
var xhr = new XMLHttpRequest();
xhr.open('GET', './02.html', true);
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
var headers = xhr.getAllResponseHeaders();
console.log(headers);
}
}
在调试界面可以看到,此时header的原始数据中是含有\r\n
这样的换行符号的。可以对其进行替换处理:
//01.js
var xhr = new XMLHttpRequest();
xhr.open('GET', './02.html', true);
xhr.send();
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
var headers = xhr.getAllResponseHeaders();
console.log(headers);
//------------字符处理
//定义数组,将header内的字符串头尾空格去掉后按照换行符进行分割存入数组
var arr = headers.trim().split(/[\r\n]+/);
var headerMap = {};
//使用数组的循环,初始化一个新的数组类型,以键值对的形态存储返回的headers
arr.forEach(function (line) {
var parts = line.split(': ');
var header = parts.shift();
var value = parts.join(': ');
headerMap[header] = value;
});
/*
函数注解:
split() 方法用于把一个字符串分割成字符串数组。
shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
join() 方法用于把数组中的所有元素转换一个字符串。元素是通过指定的分隔符进行分隔的。
*/
//打印结果
console.log(headerMap);
}
}
3.7 XMLHttpRequest.abort()
XMLHttpRequest.abort()
方法用来终止已经发出的 HTTP 请求。调用这个方法以后,readyState
属性变为4
,status
属性变为0
。
示例:5秒之后,终止一个 AJAX 请求。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.example.com/page.php', true);
setTimeout(function () {
if (xhr) {
xhr.abort();
xhr = null;
}
}, 5000);
到此,这部分的知识就大致整理完毕了。在代码学习过程中,对于其必备的调试能力确实是需要多加练习的地方。
参考链接:
https://www.php.cn/js-tutorial-411396.html AXJX同步传输异步传输的区别
以及老师的笔记文档…