Ajax,全称 Asynchronous JavaScript and XML,即异步 JavaScript 和 XML。Ajax 是浏览器和服务器之间的一种异步通信方式,最大的特点就是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
网页传统请求
网页中传统的请求:
- 超链接
- 表单
- window.location.href
传统的请求的缺点
- 会使得页面刷新
- 如果请求耗时长,页面会处于空白页
- 只能线性地同步调用请求
Ajax请求
Ajax请求的特点:
- 局部更新页面,而不会刷新整个页面
- 能够异步发起请求,不影响用户操作
- 能够一次性发起多个请求,每个请求单独一个线程
Ajax请求的切点:
- 没有浏览历史记录(不能回退)
- 存在同源跨域问题
- SEO不友好(因为数据是由Ajax请求动态获取的,不在网页源代码中)
XMLHttpRequest对象
XMLHttpRequest 是由浏览器提供的对象,是实现 Ajax 的一种方式,Ajax 请求与响应的核心都与它相关。
readyState
readyState是一个记录XMLHttpRequest对象的状态:
- 0,请求未初始化
- 1,已连接到服务器
- 2,请求已收到
- 3,请求处理中
- 4,请求已完成,响应已就绪
onreadystatechange
当readyState发生改变时,触发回调函数。
status
HTTP状态码
response
响应体
responseType
设置响应体数据类型
- arraybuffer
- blob
- document
- json
- text
responseText
响应数据,文本类型
open()
初始化请求,打开通道,方法参数为open(method, url, async, user, psw)
- method,请求方法,GET/POST
- url,请求地址
- async,是否异步请求,true/false
- username,服务器认证用户名
- password,服务器认证密码
setRequestHeader()
用于设置请求头
- setRequestHeader('Content-Type', '');
send()
用于发起请求
Ajax请求示例
Ajax get请求
<input>作为发起请求的按钮<div>作为渲染的响应数据
<input type="button" id="btn" value="click here">
<div id="d">将要渲染的数据区</div>
- 获取 XMLHttpRequest 对象
- 在 XMLHttpRequest 对象状态回调函数中编写请求逻辑
- 打开请求通道,初始化请求
- 发起请求
$('#btn').click(()=>{
// 1.获取 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
// 2.XMLHttpRequest 对象状态回调
xhr.onreadystatechange = ()=> {
console.log('readyState: ' + xhr.readyState);
// 6.1 当请求完成时
if (xhr.readyState === 4) {
// 6.2 当请求成功时
if (xhr.status === 200) {
console.log(xhr.responseText);
// 6.3 渲染数据
$('#d').text(xhr.responseText);
}
}
};
// 3.打开请求通道
xhr.open('GET', './data.json', true);
// 5.发起请求
xhr.send();
});
Ajax get带参数请求
- get请求参数在路径后拼接
?name=value&name=value...
$('#btn').click(()=>{
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = ()=> {
console.log('readyState: ' + xhr.readyState);
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.responseText);
$('#d').text(xhr.responseText);
}
}
};
xhr.open('GET', './data.json?timestamp=' + Date.now(), true);
xhr.send();
});
Ajax post表单
- 模拟表单提交需要设置请求头
Content-Type: application/x-www-form-urlencoded - 表单数据在
send()中以urlencoded格式传递
$('#btn').click(()=>{
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = ()=> {
console.log('readyState: ' + xhr.readyState);
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.responseText);
render(xhr.responseText);
}
}
};
xhr.open('POST', 'https://code.jquery.com/jquery-3.7.1.min.js', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send('timestamp=' + Date.now());
});
在控制台中请求的数据格式
Ajax 处理JSON格式响应数据
- 处理JSON格式响应数据可以设置
responseType=json,表示响应体是JSON格式数据; - 获取数据时直接访问
xhr.response
$('#btn').click(()=>{
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = ()=> {
console.log('readyState: ' + xhr.readyState);
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.response);
render(JSON.stringify(xhr.response));
}
}
};
xhr.responseType = 'json';
xhr.open('get', './data.json?timestamp=' + Date.now(), true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send();
});
Ajax请求超时/网络异常
- 通过
ontimeout回调处理请求超时 - 通过
onerror回调处理网络异常
$('#btn').click(()=>{
const xhr = new XMLHttpRequest();
// 请求超时
xhr.timeout = 2000;
xhr.ontimeout = ()=> {
alert('请求超时');
};
// 网络异常
xhr.onerror = ()=> {
alert('服务器异常');
};
xhr.open('get', './data.json?timestamp=' + Date.now(), true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send();
});
Ajax请求中止
- 通过
abort函数中止请求
$('#btn').click(()=>{
const xhr = new XMLHttpRequest();
xhr.open('get', './data.json?timestamp=' + Date.now(), true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send();
// 请求中止
xhr.abort();
});
请求抖动问题
请求抖动就是在短时间内多次发起同一个请求。为了避免请求抖动可以这样处理:
- 请求前判断是否有请求中,如有则中止请求
- 设置变量标识请求处于发送中
- 在请求状态回调中处理完成请求时设置变量标识为无请求
// 设置一个是否发送中的标识
let isSending = false;
let xhr = null;
$('#btn').click(()=>{
// 已有发送中的请求则中止
if (isSending) xhr.abort();
xhr = new XMLHttpRequest();
// 发送中
isSending = true;
xhr.onreadystatechange = ()=> {
if (xhr.readyState === 4) {
// 完成请求,设置发送中标识为false
isSending = false;
if (xhr.status === 200) {
render(JSON.stringify(xhr.response));
}
}
};
xhr.open('get', './data.json?timestamp=' + Date.now(), true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send();
});
低版本IE缓存问题
HTTP协议中规定GET请求是需要缓存的,当前后两次请求的路径完全一样时,后一次请求会直接从浏览器缓存中给直接获取前一次缓存的数据。
为避免缓存问题可以在请求URL的参数中加时间戳或随机数。
jQuery发送Ajax请求
参考《jQuery基础》
Axios发送Ajax请求
Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js。在客户端 (浏览端) 中 Axios 同样是使用 基于 XMLHttpRequest 发起 Ajax 请求。
引入axios.js
<script src="https://unpkg.com/axios@1.1.2/dist/axios.min.js"></script>
axios get请求
axios.get(url [, config])
url,请求地址config,可以设置params和header
$('#btn').click(()=>{
// axios.get(url, {params, headers})
axios.get('./data.json', {
params: {
timestamp: Date.now()
},
headers: {
name: 'wei'
}
}).then(value => {
console.log(value);
});
});
axios post请求
axios.post(url, data [, config])
url,请求地址data,请求数据config,可以设置params和header
$('#btn').click(()=>{
// axios.post(url, data, {params, headers})
axios.post('./data.json', {
name: 'wei'
}, {
params: {
timestamp: Date.now()
},
headers: {
['Content-Type']: 'application/json'
}
}).then(value => {
console.log(value);
});
});
axios get/post请求
axios({method, url [data, config]})
method,请求方法url,请求地址data,请求数据config,可以设置params和header
$('#btn').click(()=>{
axios({
method: 'POST',
url: './data.json',
params: {
timestamp: Date.now()
},
headers: {
['Content-Type']: 'application/json'
},
data: {
name: 'wei'
}
}).then(value => {
console.log(value);
});
});
fetch发送Ajax请求
fetch()是一个全局静态方法。
fetch(input [, {init}])
input,请求地址init,可以设置method,headers,body
$('#btn').click(()=>{
fetch('./data.json', {
method: 'POST',
headers: {
['Content-Type']: 'application/json'
},
body: JSON.stringify({
name: 'wei'
})
}).then(response => {
return response.json();
}).then(result => {
console.log(result);
});
});