AJAx

本文最后更新于:1 年前

AJAX

什么是AJAX

异步的javascript和xml,AJAX 是一种用于创建快速动态网页的技术。

优点

在不需要重新刷新页面的情况下,Ajax 通过异步请求加载后台数据,并在网页上呈现出来。

作用

ajax用来与后台交互
常见运用场景有表单验证是否登入成功、百度搜索下拉框提示和快递单号查询等等。
Ajax的目的是提高用户体验,较少网络数据的传输量

初识 XMLHttpRequest

要发送一个 Ajax 请求,需要经过四个步骤:初始化、连接、发送、接收

  • 初始化:XMLHttpRequest 对象

  • 连接:规定请求的类型、URL 以及是否异步处理请求。发送信息至服务器时内容编码类型

  • 发送:发送请求

  • 接收:接收服务器响应数据

    创建Ajax核心对象XMLHttpRequest(记得考虑兼容性)

    1
    2
    3
    4
    5
    6
    var xhr=null;  
    if (window.XMLHttpRequest) {// 兼容 IE7+, Firefox, Chrome, Opera, Safari
    xhr=new XMLHttpRequest();
    } else{// 兼容 IE6, IE5
    xhr=new ActiveXObject("Microsoft.XMLHTTP");
    }

    配置请求信息

    1
    2
    xhr.open("POST","test.html",true); 
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  • method:请求的类型;GET 或 POST

  • url:文件在服务器上的位置

  • async:true(异步)或 false(同步) 注意:post请求一定要设置请求头的格式内容

    向服务器发送请求

    1
    xhr.send("fname=Henry&lname=Ford");  //post请求参数放在send里面,即请求体

    服务器响应处理(区分同步跟异步两种情况)

    responseText 获得字符串形式的响应数据。
    responseXML 获得XML 形式的响应数据。

    同步处理

    1
    2
    3
    xhr.open("GET","info.txt",false);  
    xhr.send();
    document.getElementById("myDiv").innerHTML=xhr.responseText; //获取数据直接显示在页面上

    异步处理

    相对来说比较复杂,要在请求状态改变事件中处理。

    1
    2
    3
    4
    5
    6
    xhr.onreadystatechange=function()  { 
    if (xhr.readyState==4 &&xhr.status==200) {
    document.getElementById("myDiv").innerHTML=xhr.responseText;
    }
    }

    什么是readyState?

    readyState是XMLHttpRequest对象的一个属性,用来标识当前XMLHttpRequest对象处于什么状态。
    readyState总共有5个状态值,分别为0~4,每个值代表了不同的含义

  • 0:未初始化 – 尚未调用.open()方法;

  • 1:启动 – 已经调用.open()方法,但尚未调用.send()方法;

  • 2:发送 – 已经调用.send()方法,但尚未接收到响应;

  • 3:接收 – 已经接收到部分响应数据;

  • 4:完成 – 已经接收到全部响应数据,而且已经可以在客户端使用了;

    什么是status?

    HTTP状态码(status)由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进—步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

常见的状态码

仅记录在 RFC2616 上的 HTTP 状态码就达 40 种,若再加上 WebDAV(RFC4918、5842)和附加 HTTP 状态码 (RFC6585)等扩展,数量就达 60 余种。接下来,我们就介绍一下这些具有代表性的一些状态码。

  • 200 表示从客户端发来的请求在服务器端被正常处理了。
  • 204 表示请求处理成功,但没有资源返回。
  • 301 表示永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。
  • 302 表示临时性重定向。
  • 304 表示客户端发送附带条件的请求时(指采用GET方法的请求报文中包含if-matched,if-modified-since,if-none-match,if-range,if-unmodified-since任一个首部)服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)
  • 400 表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。
  • 401 表示未授权(Unauthorized),当前请求需要用户验证
  • 403 表示对请求资源的访问被服务器拒绝了
  • 404 表示服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
  • 500 表示服务器端在执行请求时发生了错误。也有可能是Web应用存在的bug或某些临时的故障。
  • 503 表示服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

使用举例如下,使用 XMLHttpRequest 对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 1. 初始化 创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();

// 2. 连接
xhr.open('GET', url, true);

// 3. 发送
xhr.send('hello world');

// 4. 接收
xhr.onreadystatechange = function (e) {
var status = xhr.status;

if (xhr.readyState == 4) {
if ((status >= 200 && status < 300) || status == 304) {
fnSucc(xhr.responseText);
} else {
fnFail(xhr);
}
}
};

其中,xhr.send() 是异步的,所以放在第三步或第四步都行。

封装AJAX

上面的代码段是可以复用的,因此我们用函数将其封装起来,并提供一些可配置的参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var ajax = function (method, url, body, fnSucc, fnFail) {
var xhr = new XMLHttpRequest();

xhr.open(method, url, true);
xhr.send(body);
xhr.onreadystatechange = function (e) {
var status = xhr.status;

if (xhr.readyState == 4) {
if ((status >= 200 && status < 300) || status == 304) {
fnSucc(xhr.response);
} else {
fnFail(xhr);
}
}
};
};

使用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
ajax(
'GET',
'/api.json',
'',
// 成功回调
function (res) {
console.log('res', res);
},
// 失败回调
function (e) {
console.log('e', e);
}
);

使用 Promise

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
const ajax = function ({ url, method, data, headers }) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()

xhr.open(method, url, true)

for (const key in headers) {
const value = headers[key]
xhr.setRequestHeader(key, value)
}

xhr.send(data)
xhr.onreadystatechange = function () {
const state = xhr.readyState
const status = xhr.status

if (state == 4) {
if ((status >= 200 && status < 300) || status == 304) {
resolve(xhr.response)
} else {
reject(xhr)
}
}
}
})
}

使用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ajax({
url: '/api.json',
method: 'GET',
data: { name: 'liuyib', age: 22 },
headers: {
'Content-Type': 'text/plain',
},
})
.then((res) => {
console.log('res', res)
})
.catch((err) => {
console.log('err', err)
})

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!