简介
Ajax(Asynchronous JavaScript and XML ,异步通信 Javascript 和 XML) 是利用 JavaScript 脚本和 XML 数据实现客户端和服务端进行异步通信的一种方法。
- 基于标准的 HTML 和 CSS
- 通过 DOM 实现动态显示和交互
- 通过 XML 进行数据交互和处理
- 使用 XMLHttpRequest 插件进行异步通信
- 使用 Javascript 实施逻辑控制,以便整合上述技术
头部信息
HTTP(HyperText Transfer Protocol ,超文本传输协议)是一种应用层协议,负责超文本传输。如文本、图像、多媒体等。 HTTP 由两部分组成:请求( Request )和响应( Response )。
请求
HTTP 由三部分组成:请求头、消息报头、请求正文。
<request-line>
<headers>
<blank line> [<request-body>] ></request-body></blank></headers
></request-line
>
请求头以一个方法符号开头,以空格隔开。后面跟着请求的 URL 和协议的版本号。
method Request-URI HTTP-Version CRLF
各部分说明如下:
- Method ∶表示请求方法,请求方法以大写形式显示,如 POST 、 GET 等。 HTTP 定义了大量的 请求类型,不过 Web 开发常用 GET 和 POST 请求。只要在 Web 浏览器上输入一个 URL ,浏览器就将基于该 URL 向服务器发送一个 GET 请求,以告诉服务器获取并返回什么资源
- Request-URI ∶ 表示统一资源标识符
- HTTP-Version ∶ 表示请求的 HTTP 协议版本
- CRLF ∶表示回车和换行,除了作为结尾的 CRLF 外,不允许出现单独的 CR 或 LF 字符。
请求行后是消息报头部分,用来说明服务器需要调用的附加信息。 在消息报头后是一个空行,然后才是请求正文部分,即主体部分( body ),该部分可以添加任意的其它数据。
GET / HTTP / 1.1 HOST: www.baidu.com <User - Agent: Mozilla / 5.0(Window; U; Window NT 5.1; zh - CN; rv: 1.9 .0
.8) Gecko / 2021040629 Chrome /91.0.4464.4
Connection:keep-Alive
- 请求行的第1部分说明了该请求是 GET 请求。该行的第 2 部分是一个斜杠(/),用来说明请轴是百度域名的根目录。该行的最后一部分说明使用的是 HTTP1.1版本,另一个可选项是 HTTP1.0
- 第2行是请求的第一个消息报头, HOST 头部指出请求的域名。结合 HOST 头部和上一行中的统资源标识符(即斜杠),就可以确定请求服务器的具体地址
- 第3行包含的是 User-Agent 头部,服务器端和客户端脚本都能够访问它,该头部包含的信息由浏览器来定义,并且在每个请求中将会自动发送。 JavaScript 和服务器通过 User-Agent 头部信息,可以了解客户端的本地情况
- 最后一行是 Connection 头部,通常将浏览器操作设置为 Keep-Alive ,在最后一个头部后有一个空行(即使不存在请求主体)
如果在 GET 请求中附带参数,则必须将这些附带信息加在 URL 后,这个信息别称为查询字符串( Query String ),发送时被附加在请求行中。
GET /bbs/?user=css8%20 HTTP / 1.1 HOST: lmssee.cn <User - Agent: Mozilla / 5.0(Window; U; Window NT 5.1; zh - CN; rv: 1.9 .0
.8) Gecko / 2021040629 Chrome /91.0.4464.4
Connection:keep-Alive
在 POST 请求中,被要求服务器就收附在请求后面数据,常用于提交表单
POST /form.asp HTTP/(CRLE) HOST:www.lmssee.cn(CRLE) < User-Agent:Mozilla/5.0
(Window;U;Windows NT 5.1;zh-CN;rv:1.9.0.8) Gecko/2021040612 Chrome/91.0.4464.4
Content-Type:application/x-www-from/urlencoded Content-Length:22(CRLE)
Connection:Keep-Alive(CRLE) CAche-Control:no-cache(CRLE) <(CRLE)
// 改 CRLE 行表示消息报头已经结束,在此之前为消息报头
user=css8&pwd=111111 // 此行为提交的数据
POST 请求与 GET 请求之间略有区别。首先,请求行开始处的 GET 变为 POST ,在后面有两个新其中 Content-Type 说明了请求主体的内容是如何编码的。浏览器始终以 application/x-www-from-urlencoded 的编码格式来传送数据,这是针对简单 URL 编码的 MIME 类型。
Content-Length 说明了请求主体的字节数。在 Connection 后是一个空行,再后面就是请求主体。大多数浏览器的 POST 请求一样,都以"名称/值"对的形式表示的。 POST 方法与 GET 方法的数据传形式几乎是一样的。
响应
HTTP 响应也是三部分组成:状态行、消息报头、响应正文。
<status-line>
<headers>
<blank line> [<response-body>] </response-body></blank></headers
></status-line
>
状态行内容如下:
HTTP-Version Status-Code Reason-Phrase CRLE
- HTTP-Version ∶ 表示服务器 HTTP 协议的版本
- Status-Code ∶ 表示服务器发回的响应状态代码
- Reason-Phrase ∶ 表示状态代码的文本描述
状态代码有3位数字组成,第一个数字定义了响应的类别,且有如下5种可能的取值。
-
1xx ∶指示信息。表示请求已接收,继续处理
-
2xx ∶ 成功。表示请求已被成功接收、理解或接收
-
3xx ∶ 重定向。要完成请求必须进行更进一步的操作
-
4xx ∶ 客户端错误。请求有语法错误,或者请求无法实现
-
5xx ∶ 服务器端错误。服务器未能实现合法的请求
-
200 oK 客户端请求成功
-
400 Bad Request 客户端请求有语法错误,不能被服务器所理解
-
401 Unauthorized 请求未经授权,这个状态代码必须和 wwW-Authenticate 报头域一起使用
-
403 Forbidden 服务器收到请求,但是拒绝提供服务
-
404 Not Found 请求资源不存在,例如,输入了错误的 UR
-
500 Internal Server Error 服务器发生不可预期的错误
-
503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后,可能恢复正常
在状态行之后是消息头。 一般服务器会返回一个名为 Data 的信息, 用来说明响应生成的日期和时间。 接下来就是与 POST 请求中一样的 Content - Type 和 Content - Length 。 响应主体所包含的就是所请求资源的 HTML 源文件。
HTTP/1.1 200 OK Date: Wed,08 Apr 2021 12:55:50 GMT Content-Type:
text/html;charset=gb2312 Content-Length: 1700
<html>
<head>
<title>百度一下,你就知道</title>
</head>
<body>
<!-- body -->
</body>
</html>
转换串行化字符串
GET 和 POST 都是以名值对字符串的形式发送数据。
传输名/值对信息
与 JavaScript 对象结构类似,多在 GET 请求中使用。
传输有序数据列表
与 JavaScript 数组结构类似,多在一系列文本框中提交表单信息时使用,它与上一种方式不同,说提交的数据按顺序排列,不可以随意组合。
function toString(data) {
var a = [];
if (data.constructor == Array) {
for (var i = 0; i < data.length; i++) {
a.push(data[i].name + '=' + encodeURIComponent(data[i].value));
}
} else {
for (var i in data) {
a.push(i + '=' + encodeURIComponent(data[i]));
}
}
return a.join('&');
}
跟踪状态
XMLHttpRequest 对象通过 readyState 属性实时跟踪异步状态。一旦当该属性发生变化,皆会触发 readystatechange 事件,调用该事件绑定的回调函数。
返回值 | 嗯 |
---|---|
0 | 未初始化。表明对象已经建立,但是未初始化,尚未调用 open() 方法 |
1 | 初始化。表明对象已经建立,尚未调用 send() 方法 |
2 | 发送数据。表示 send() 方法已经调用,但是当前的状态以及 HTTP 头未知 |
3 | 数据传送中。已经结束部分数据,因为响应及 HTTP 不全,这时通过 responseBody 和 responseText 获取部分数据会出现错误 |
4 | 完毕。数据加载完毕,此时可以通过 responseBody 和 responseText 获取完整的响应数据 |
如果 readyState 属性值是 4 ,这说明相应完毕,那么可以安全的读取数据。另外,还需要监控 HTTP 状态码,只有当 HTTP 状态码为 200 时,才表示 HTTP 响应顺利完成。
在 XMLHttpRequest 中使用 states 属性获取当前的 HTTP 状态码。如果是 readyState 属性值为 4,且 state (状态码)属性值为 200,那么说明 HTTP 请求过程顺利完成。
// 定义 XMLHttpRequest 对象// 参数:无
// 返回值: XMLHttpRequest 对象实例
function createXMLHTTPObject() {
var XMLHttpFactories = [
// 兼容不同浏览器和版本的创建函数数组
function () {
return new XMLHttpRequest();
},
function () {
return new ActiveXObject('Msxml2.XMLHTTP');
},
function () {
return new ActiveXObject('Msxml3.XMLHTTP');
},
function () {
return new ActiveXObject('Microsoft.XMLHTTP');
},
];
var xmlhttp = false;
for (var i = 0; i < XMLHttpFactories.length; i++) {
// 尝试调用匿名函数,如果成功则返回 XMLHttpRequest 对象,否则继续调用下一个
try {
xmlhttp = XMLHttpFactories[i]();
} catch (e) {
continue;
// 如果发生异常,则继续下一个函数调用
}
break; // 如果成功,则中止循环
}
return xmlhttp; // 返回对象实例
}
var xmlHttp = createXMLHTTPObject();
function request(url) {
xmlHttp.open('GET', url, false);
xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.send(null);
}
function handleStateChange() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200 || xmlHttp.status == 0) {
alert(xmlHttp.responseText);
}
}
}
终止请求
使用 abort() 方法可以终止正在进行的异步请求。在使用 abort() 方法前,应先清除 onreadystatechange 事件处理函数,因为 IE 和 Mozilla 在请求中止后也会激活这个处理函数,如果给 onreadystatechange 属性设置为 null ,则 IE 会发生异常,所以可以设置一个空函数。
xmlhttp.onreadystatechange = function () {};
xmlhttp.abort();