写在前面
这个封装只包括最简单的get,post方法,主要是仿照jQuery中的ajax()函数,使用方法也类似。
1. 创建XMLHttpRequest异步对象
那么什么是XMLHttpRequest对象呢?
XMLHttpRequest是ajax的基础,XMLHttpRequest对象用于和服务器交换数据并且获得服务器的响应。XMLHtppRequest用于在后台与服务器交换数据,这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
下面是创建一个异步对象的代码。
var xmlhttp;
if (window.XMLHttpRequest)
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp = new XMLHttpRequest();
else
// IE6, IE5 浏览器执行代码
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
2. 设置请求方式和请求地址并发送请求
用到XMLHttpRequest对象的open和send方法向服务器发送请求。
open(method, url, async)
// method - 请求类型 GET或是POST
// url - 文件在服务器上的位置
// async - 异步true 同步false
send(string)
// string - 仅用于post请求
// GET请求时可以sned()或是send(null)
2.1 GET or POST
GET相对于POST更快也更简单,适用于大部分情况。
当遇到下列情形时必须使用POST
- 需要更新服务器上的文件或数据库
- 向服务器发送大量数据
- 发送包含未知字符的用户输入时,POST比GET更稳定可靠
2.2 GET请求
一些GET实例
xmlhttp.open("GET", "try/test.php", true);
xmlhttp.send();
// 可能得到缓存的结果,所以可以向url中添加唯一的ID
xmlhttp.open("GET", "try/test.php?t=" + Math.random(), true);
// 如果需要发送信息,则将信息添加到url中,格式如下
xmlhttp.open("GET", "try/test.php?title=ajax&name=xuejiachen", true);
通过上面的例子我们可以知道GET请求的基本格式,如果需要发送信息时,对data进行相应的格式处理添加到url后面即可。所以在我们这个封装ajax的例子中,我们这样操作:
// 对option.data进行预处理
let params = [];
Object.keys(option.data).forEach(key => {
params.push(key + '= ' + option.data[key]);
})
let sendData = params.join('&');
if(option.type === "GET") {
xhr.open("GET", option.url + '?' + sendData, true);
xhr.send(null);
}
2.3 POST请求
POST 数据时,需要使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定希望发送的数据。
// 一个简单的post例子
xmlhttp.open("POST", "try/demo.php", true);
xmlhttp.send();
// 当需要POST数据时,则必须要添加HTTP头
setRequestHeader(header, value)
// header - 规定头的名称
// value - 规定头的值
xmlhttp.open("POST", "try/test.php", true);
xmlhttp.setRequestHeader("Content-type", "appliaction/x-www-form-urlencoded");
xmlhttp.send("title=ajax&name=xuejiachen");
setRequestHeader()又可以分为表单格式或是json格式
xhr.open("POST", option.url, true);
// 设置提交时的内容类型
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhr.send(JSON.stringify(option.data));
// 若数据为表单格式
xhr.setRequestHeader('Content-Type', 'application/x-ww-form-urlencoded');
xhr.send(sendData); // 这里的sendData与之前GET方法中加在url后面的数据格式一致
3. 监听状态的变化,处理返回的结果
这里涉及到XMLHttpRequest对象三个重要的属性onreadystatechange, readyState, status
onreadystatechange
存储函数名,每当readyState属性改变时,就会调用该函数
readyState 返回当前文档的载入状态
0 - 请求未初始化 还没有调用send()方法
1 - 服务器连接已建立 已调用send()方法,正在发送请求
2 - 请求已接收 send()方法执行完成,已经接收到全部响应内容
3 - 请求处理中 正在解析响应内容
4 - 请求已完成 响应内容及解析完成,可以在客户端调用了
status
200 'OK'
404 未找到页面
当readyState等于4且state为200时,表示响应已就绪;在这里接收后台返回的数据。
下面是整个过程的代码
function ajax(option) {
option = option || {};
option.type = (option.type || "GET").toUpperCase();
option.dataType = option.dataType || "json";
// 1.创建一个异步对象
const xhr;
// 考虑兼容性
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
// 兼容IE6以下版本
else if(window.ActiveXObject) {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
// 2.设置请求方式和请求地址
// 3.发送请求
// 对option.data进行预处理
let params = [];
Object.keys(option.data).forEach(key => {
params.push(key + '= ' + option.data[key]);
})
let sendData = params.join('&');
if(option.type === "GET") {
xhr.open("GET", option.url + '?' + sendData, true);
xhr.send(null);
}
else if(option.type === "POST") {
xhr.open("POST", option.url, true);
// 设置表单提交时的内容类型
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhr.send(JSON.stringify(option.data));
// 若数据为表单格式
// xhr.setRequestHeader('Content-Type', 'application/x-ww-form-urlencoded');
// xhr.send(sendData);
}
// 4.监听状态的变化
// 5.处理返回的结果
/* onreadystatechange
存储函数名,每当readyState属性改变时,就会调用该函数*/
/* readyState 返回当前文档的载入状态
0 - 请求未初始化 还没有调用send()方法
1 - 服务器连接已建立 已调用send()方法,正在发送请求
2 - 请求已接收 send()方法执行完成,已经接收到全部响应内容
3 - 请求处理中 正在解析响应内容
4 - 请求已完成 响应内容及解析完成,可以在客户端调用了*/
/* status
200 'OK'
404 未找到页面*/
xhr.onreadystatechange = () => {
if(xhr.readyState === 4) {
let status = xhr.status;
if(status === 200) {
let response = xhr.responseText;
if(responseType === 'json') { // ?
response = JSON.parse(xhr.responseText); // 将ajax返回的data转为对象格式
}
option.onSuccess(response, xhr);
}
else {
option.onError(xhr);
}
}
}
}