0x01 Axaj简介

(1)概述

AJAX = 异步 JavaScript 和 XML。

AJAX 是一种用于创建快速动态网页的技术。

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

(2)Ajax的执行过程

使用Ajax技术通常包括以下几个步骤:

  • 创建一个Ajax对象。
  • 在此对象的基础上根据HTTP协议的规范向服务器发送HTTP请求。
  • 服务器接收到Ajax请求后会响应此请求,并根据事先约定的格式返回相应的数据集。
  • 浏览器接收到服务器的响应,获取返回数据集,更新部分网页内容。

用一句话概括,即Ajax通过XMLHttpRequest对象向服务器发出HTTP请求,当获取到服务器返回的数据后进行相应的页面数据的渲染处理。


0x02 XHR对象创建

Ajax的核心是XMLHttpRequest对象(简称为XHR对象)的使用,XMLHttpRequest对象作为浏览器请求服务器的一个接口,可以使用异步的方式通过浏览器向服务器发送请求并解析服务器的响应。

使用Ajax服务器发送HTTP请求的首要任务是创建一个XMLHttpRequest对象,也称实例化XHR对象,代码如下:

1
2
3
<script type="text/javascript">
var xhr = new XMLHttpRequest();
</script>


0x03 Ajax发送请求

(1)open() 方法

用法:

1
open(method,url,async)

规定请求的类型、URL 以及是否异步处理请求。

  • method:请求的类型;GET 或 POST
  • url:文件在服务器上的位置
  • async:true(异步)或 false(同步)

demo:

1
2
3
4
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open("get", "./Ajax/demo_get.php", true);
</script>

(2)send() 方法

用法:

1
send(string)

open()方法执行完毕后,调用send()方法通过HTTP协议将请求发送到服务器。

如果为GET请求,send()方法无参数,默认为null;如果为POST请求,则send()方法的参数为要发送的数据。

demo:

1
2
3
4
5
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open("get", "./Ajax/demo_get.php", true);
xhr.sned(null);
</script>


0x04 Ajax接收响应

浏览器接收到服务器的响应后,信息可以通过XMLHttpRequest对象的属性和方法使用。在使用XHR对象接收响应的过程中有四个常用的属性,分别为:

  • status:以数字形式返回HTTP响应的状态码。
  • responseText:以文本形式作为响应主体被返回。
  • responseXML:如果响应的内容类型。是”text/xml”或”application/xml”,那么此属性将以document形式返回保存响应数据的XML DOM文档。
  • statusText:以文本形式返回HTTP的状态说明。

demo:

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open("get", "./Ajax/demo_get.php", false); //同步请求
xhr.send(null);
//判断请求是否成功
if(xhr.status == 200 || xhr.status == 304){
alert(xhr.responseText); //打印响应数据
}else{
alert("请求失败,状态码为:" + xhr.status);
}
</script>


0x05 异步Ajax

如果设置open()方法的第三个参数值为true,则表示Ajax需要异步处理请求。此时,需要判断服务器响应的数据是否传送完成,检测XHR对象中的readState属性的状态码是否为4.

readySate属性表示请求/响应过程当前的状态,如下表:

状态码 状态 说明
0 未初始化 尚未调用open方法
1 启动 已经调用open(),尚未调用send()
2 发送 已经调用send(),但尚未收到头信息
3 接收 已经接收到部分相应的主题信息
4 完成 已经接收到全部响应数据,且可以在客户端使用

理论上,Ajax发送请求处理响应的过程中只要readState的状态码改变一次,就会触发readystatechange事件,因此可以利用这个事件来检测每次状态变化后readySate的值,来判断当前Ajax接收数据的状态。

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

//创建onreadystatechange事件监测Ajax状态变化
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","/ajax/test1.txt",true);
xmlhttp.send();
}
</script>
</head>
<body>

<div id="myDiv"><h2>Let AJAX change this text</h2></div>
<button type="button" onclick="loadXMLDoc()">通过 AJAX 改变内容</button>

</body>
</html>


0x06 JSON数据传递

目前Ajax技术进行数据传递时,采用JSON格式的数据进行传递已经成为事实上的标准。相较与XML而言,使用JSON格式的数据传递实现简单且方便。采用JSON格式的数据进行传递时,往往应用于数据量比较多,且需要清晰传递的情况。但是此种方式传递需要将服务器返回的JSON格式字符串先转化为Javascript对象。

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>
<input type="button" onclick="info();" value="info">
<p id="name"></h1>
<p id="age"></p>
<p id="school"></p>
</body>
<script>
function info(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(this.readyState == 4){
var person = eval('(' + this.responseText + ')');
console.log(person);
document.getElementById('name').innerHTML = "name:" + person.name;
document.getElementById('age').innerHTML = "age:" + person.age;
document.getElementById('school').innerHTML = "school:" + person.school;
}
}
xhr.open('get', 'ajax_json.php', true);
xhr.send();
}
</script>

说明:eval()方法可以将JSON字符串转换为JSON对象。

服务端的返回的JSON格式的数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$person = [];
$person[] = array('name' => 'Lethe',
'age' => '19',
'school' => 'CUMT');
$person[] = array('name' => 'Jack',
'age' => '20',
'school' => 'B');
$person[] = array('name' => 'Ben',
'age' => '20',
'school' => 'C');
$n = mt_rand(0,2);
echo json_encode($person[$n]);
?>

在这里插入图片描述


0x06 查询缓存

为了避免缓存带来的影响,可以向URL中添加一个随机数或者时间戳作为请求数据的一部分,发送给服务器,以保证当前的请求始终为首次发送。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<body>
<input type="text" name="username">
</body>
<script type="text/javascript">
var username = document.getElementsByName("username")[0];
username.onblur = function()
{
var xhr = new XMLHttpRequest();
var url = "./Ajax/demo_get.php?username=" + encodeURIComponent(this.value);
xhr.onreadystatechange = function(){
if(xhr.status == 4){
alert(this.responseText);
}
}
xhr.open('GET',url+'&num'+Math.random(), true);
xhr.sned(null);
}
</script>


0x07 Ajax函数封装

使用Ajax发送HTTP请求通常有如下几个步骤:

  • 实例化XMLHttpRequest对象

  • 通过open()方法规定Ajax发送的请求类型、服务器URL地址,以及是否为异步处理请求。

  • 通过send()方法发送使用open()方法定义好的Ajax请求,并根据XMLHttpRequest对象中规定的具体参数判断Ajax请求响应的状态,根据不同的状态进行不同的操作。

使用Ajax的步骤基本固定,因此可以把上述步骤抽象出来封装成一个Ajax方法,当需要调用Ajax时,直接调用此方法即可,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<script type="text/javascript">
function ajax(obj){
// 创建XHR对象,并设置Ajax默认为GET请求方式,设置回调函数异步处理请求,返回响应
obj.method = obj.method || 'get';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){ //异步处理请求,接收响应
if((xhr.status == 4)&&(xhr.status == 200)){
//callback()为回调函数,若不设置则无回调
obj.callback && obj.callback(xhr.responseText);
}
}
//分别用GET和POST两种方式创建查询字符串,用来保护用户提交的数据信息,并分别发送Ajax异步请求
var strData = '';
if(obj.method == 'post'){
for(var key in obj.data){
strData += '&' + key + '=' + obj.data[key];
}
strData = strData.substring(1); //去掉开头多余的&
xhr.open('post', obj.url, true);
//设置请求头
xhr.setRequestHeader("content-type", "application/x-www-form-urlencode");
xhr.send(strData);
}else{
//如果是GET方式,则需要对数据进行编码
for(var key in obj.data){
strData += '&' + encodeURIComponent(key) + '=' + encodeURIComponent(obj.data[key]);
}
//去掉多余的&,并增加时间戳,防止缓存
strData = strData.substring(1) + '&' + Number(new Data());
xhr.open('get', obj.url + '?' + strData, true);
xhr.send(null);
}
}
</script>

调用事例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
html code...

<script type="text/javascript">
btn.onclick = function({
ajax({
url: '/ajax/demo.php',
method: 'GET',
data: {year:year.value, month:month.value, day:dat.value},
callback: function(data){
result.innerHTML = data;
}
})
})
</script>