文章目录
- ajax
- 工作原理
- ajax发请求四个步骤
- 创建xmlhttprequest对象
- 设置请求方式
- 设置回调函数
- 发送请求
- 自封装ajax
- axios
- axios 特性
- 如何用
- 配置拦截器
- fetch
- 三者区别
ajax
工作原理
Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器。像—些数据验证和数据处理等都交给Ajax引擎自己来做,,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
ajax发请求四个步骤
创建xmlhttprequest对象
//第一步:创建XMLHttpRequest对象
var xmlHttp;
if (window.XMLHttpRequest) { //非IE
xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) { //IE
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
}
设置请求方式
xmlHttp.open("POST", url, true);
设置回调函数
//第三步:注册回调函数
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
......
} else {
......
}
}
}
xmlHttp.readyState是存有XMLHttpRequest 的状态。从 0 到 4 发生变化。0: 请求未初始化。1: 服务器连接已建立。2: 请求已接收。3: 请求处理中。4: 请求已完成,且响应已就绪
具体状态码如下:
AJAX状态码说明
1**:请求收到,继续处理
2**:操作成功收到,分析、接受
3**:完成此请求必须进一步处理
4**:请求包含一个错误语法或不能完成
5**:服务器执行一个完全有效请求失败
再具体就如下:
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本
发送请求
xmlHttp.send(params)
自封装ajax
封装get方法
let Aget={
createXHR: function(){
if(window.XMLHttpRequest){
return new XMLHttpRequest()
}else{
return new ActiveXObject()
}
},
get:function(url,data,callback,dataType){
//避免dataType大小写
let dataType = dataType.toLowerCase()
if(data){
url+='?'
Object.keys(data).forEach(key => url+=`${key}=${data[key]}&`)
url=url.slice(0,-1)
}
let xhr=this.createXHR()
//创建请求
xhr.open('get',url)
//发送请求
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300||xhr.status==304){
let res = dataType=='json'? JSON.parse(xhr.responseText) : xhr.responseText
callback(res,xhr.status,xhr)
}
}
}
}
}
封装post方法
let Pget={
createXHR: function(){
if(window.XMLHttpRequest){
return new XMLHttpRequest()
}else{
return new ActiveXObject()
}
},
get:function(url,data,callback,dataType){
//避免dataType大小写
let dataType = dataType.toLowerCase()
let xhr=this.createXHR()
let str=''
if(data){
Object.keys(data).forEach(key => str+=`${key}=${data[key]}&`)
str=str.slice(0,-1)
}
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
//发送请求
xhr.send(str)
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if(xhr.status>=200&&xhr.status<300||xhr.status==304){
let res = dataType=='json'? JSON.parse(xhr.responseText) : xhr.responseText
callback(res,xhr.status,xhr)
}
}
}
}
}
封装请求
let aj={
createXHR: function(){
if(window.XMLHttpRequest){
return new XMLHttpRequest()
} else{
return new ActiveXObject()
}
},
ajax:function(params){
let type = params.type ? params.toLowerCase() :'get'
let isAsync=params.isAsync? params.isAsync : 'true'
let url=params.url
let data= params.data ? params.data :{}
let dataType = params.dataType.toLowerCase()
let xhr=createXHR()
let str=''
Object.keys(data).forEach(key=>str+=`${key}=${data[key]}&`)
if(type==='get') url+=`?${str}`
return new Promise((resolve, reject) => {
xhr.open(type,url,isAsync)
if (type=='post'){
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(str)
}else{
xhr.send()
}
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200&&xhr.status<300|| xhr.status==304){
let res=dataType==='json'? JSON.parse(responseText): responseText
resolve(res)
}else{
reject(xhr.status)
}
}
}
})
}
}
axios
axios 特性
基于promise的异步ajax请求库
浏览器端/node端都可以使用
支持请求/响应拦截器
支持请求取消
请求/响应数据转换
批量发送多个请求
如何用
const axios = require('axios');
// 向给定ID的用户发起请求
axios.get('/user?ID=12345')
.then(function (response) {
// 处理成功情况
console.log(response);
})
.catch(function (error) {
// 处理错误情况
console.log(error);
})
.finally(function () {
// 总是会执行
});
// 上述请求也可以按以下方式完成(可选)
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
.finally(function () {
// 总是会执行
});
// 支持async/await用法
async function getUser() {
try {
const response = await axios.get('/user?ID=12345');
console.log(response);
} catch (error) {
console.error(error);
}
}
配置拦截器
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
fetch
Fetch 是在 ES6 出现的,它使用了 ES6 提出的 promise 对象。它是 XMLHttpRequest 的替代品。
很多小伙伴会把它与 Ajax 作比较,其实这是不对的,我们通常所说的 Ajax 是指使用 XMLHttpRequest 实现的 Ajax,所以真正应该和 XMLHttpRequest 作比较。
Fetch 是一个 API,它是真实存在的,它是基于 promise 的。
特点:
使用 promise,不使用回调函数。
采用模块化设计,比如 rep、res 等对象分散开来,比较友好。
通过数据流对象处理数据,可以提高网站性能。
所以这里就和 Ajax 又很大不同了,一个是思想,一个是真实存在的 API,不过它们都是用来给网络请求服务的,我们一起来看看利用 Fetch 实现网络请求。
<body>
<script>
function ajaxFetch(url) {
fetch(url).then(res => res.json()).then(data => {
console.info(data)
})
}
ajaxFetch('https://smallpig.site/api/category/getCategory')
</script>
</body>