前文中,我们简单提到了JQuery为我们封装好的AJAX函数$.get()/$.post()/$.ajax()。
其实还有其他的第三方库也为我们封装好了简单易用的AJAX函数,但它们的底层都是在使用XMLHttpRequest这个对象来发起AJAX请求。接下来我们就深入了解一下怎么使用这个对象来完成AJAX操作。
- XHR的基本使用
xhr的请求状态readyState属性,用来表示当前AJAX请求所处的状态。每个AJAX请求必然处于以下五个状态中的一个:
| 值 | 状态 | 描述 |
|---|---|---|
| 0 | UNSENT | XHR对象已经被创建,但尚未调用open方法 |
| 1 | OPENED | open()方法已经被调用 |
| 2 | HEADERS_RECEIVED | send()方法已经被调用,响应头也已经被接收 |
| 3 | LOADING | 数据接收中,此时response属性中已经包含部分数据 |
| 4 | DONE | AJAX请求完成,这意味着数据传输已经彻底成功或失败 |
- 发起GET请求
// 1. 创建XHR对象
let xhr = new XMLHttpRequest();
// 2. 调用open函数,指定请求方式与URL地址
xhr.open('GET', 'https://www.juejin.cn/Citizen7');
// 3. 调用send函数,发起AJAX请求
xhr.send();
// 4. 当xhr对象的readyState属性改变的时候调用下面函数
xhr.onreadystatechange = function() {
// 4.1 监听xhr对象的请求状态readyState与服务器的响应状态status
if (xhr.readyState === 4 && xhr.status === 200) {
// 4.2 处理服务器响应回来的数据
console.log(xhr.responseText);
};
};
若是想在发起GET请求的同时传递参数呢?——只需要在URL地址后面拼接上我们需要传递的参数,这种叫做查询字符串。
...
// 2. 调用open函数,指定请求方式与URL地址
xhr.open('GET','https://www.juejin.cn/Citizen7?id=1&name=lee');
...
值得注意的是,URL地址中只允许出现英文字母、标点符号和数字,不允许出现中文。但如果我们真的需要传递一个中文作为参数,就需要对中文字符进行编码,即URL编码。就像这样:https://www.juejin.cn/Citizen7?id=1&name=%E8%A5%BF%E6%B8%B8%E8%AE%B0
- 发起POST请求
// 1. 创建XHR对象
let xhr = new HMLHttpRequest();
// 2. 调用open函数,指定请求方式与URL地址
xhr.open('POST', 'https://www.juejin.cn/Citizen7');
// 3. 设置请求头的Content-Type属性
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 4. 调用send函数,发起AJAX请求,同时将数据以查询字符串的形式提交给服务器
xhr.send('id=1&name=lee');
// 5. 当xhr对象的readyState属性改变的时候调用下面函数
xhr.onreadystatechange = function() {
// 5.1 监听xhr对象的请求状态readyState与服务器的响应状态status
if (xhr.readyState === 4 && xhr.status === 200) {
// 5.2 处理服务器响应回来的数据
console.log(xhr.responseText);
};
};
- 数据交换格式 数据交换格式,就是服务器与客户端之间进行数据传输与交换的格式。
常见的数据交换格式有XML和JSON。
- XML XML即可拓展标记语言,与HTML类似也是一种标记语言,但这两者没有任何关系。
<note>
<to>Lee</to>
<from>May</from>
<heading>通知</heading>
<body>晚上开会</body>
</note>
其实在前端中使用XML作为数据交换格式的情况比较少,主要是因为XML格式臃肿,与数据无关的代码较多,传输效率低,不仅如此,在JS中解析XML也是一件麻烦事。
- JSON JSON即JavaScript对象表示法。简单来讲,JSON就是JS对象和数组的字符串表示法,它使用文本来表示一个JS对象或数组,因此JSON的本质就是字符串。JSON与XML相比更小、更快、更容易解析。
{
"name": "lee",
"age": 20,
"gender": "男",
"address": null,
"hobby": ["吃饭", "睡觉", "打篮球"]
}
可以用JSON.parse()将JSON字符串转换成JS对象
可以用JSON.stringify将JS对象转换成JSON字符串
- 封装自己的AJAX
- 封装函数
/**
* 把传入的参数转变成查询字符串的函数
* @param {data} 需要发送到服务器的数据,是对象形式
* @returns {string} 返回拼接好的查询字符串
*/
function resovleData(data) {
let arr = [];
for (let k in data) {
// 拼接字符串然后压入到数组中
arr.push(k + '=' + data[k]);
}
// 把数组中的所有元素用 & 连接,然后作为一个字符串返回
return arr.join('&');
}
/**
* 封装的AJAX函数
* @param {options} 配置对象
*/
function myAjax(options) {
let xhr = new XMLHttpRequest();
// 把从配置对象里传递过来的参数转变为查询字符串
let qs = resovleData(options.data);
if (options.method.toUpperCase() === 'GET') {
// 发起GET请求
xhr.open('GET', options.url + '?' + qs);
xhr.send();
}
else if (options.method.toUpperCase() === 'POST') {
//发起POST请求
xhr.open('POST', options.url);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(qs);
}
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// 把响应回来的JSON字符串转变为JS对象
let result = JSON.parse(xhr.responseText);
// 调用配置对象里的回调函数,并把请求结果作为参数传入
options.success(result);
}
}
}
- 测试
<script>
myAjax({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
data: {
id: 1
},
success: function (res) {
console.log(res);
}
});
myAjax({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/addbook',
data: {
bookname: '百年孤独',
author: '加西亚·马尔克斯',
publisher: '南海出版社'
},
success: function (res) {
console.log(res);
}
});
</script>
3.结果
- axios
-
什么是axios axios是专注于网络数据请求的第三方库。相比于原生的XMLHttpRequest对象,axios更简单易用。相比于JQuery,axios因为只关注网络请求,所以更加轻量化。
-
axios的基本使用
axios.get('url', { params: { /* 参数 */ } }).then(callback);
axios.post('url', { /* 参数 */ }).then(callback);
axios({
method: 'GET',
url: 'http://www.juejin.cn/Citizen7',
params: {
name: 'lee',
id: 7
}
}).then(function(res) {
/* 成功之后的回调函数,处理传入的请求结果 */
});
axios({
method: 'POST',
url: 'http://www.juejin.cn/Citizen7',
data: { // POST的数据需要通过data属性提供
name: 'lee',
id: 7
}
}).then(function(res) {
/* 成功之后的回调函数,处理传入的请求结果 */
});