跳到主要内容

简介

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();