一、axios简介
1.1 axios概述
- 前端最流行的ajax请求库
- react/vue官方都推荐使用axios 发ajax 请求
- 文档: https://github.com/axios/axios
- axios中文网:axios中文网|axios API 中文文档
1.2 axios特点
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应 (就是有interceptor)
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
简单介绍一下promise吧。(ps:高手写代码用的都是面向对象,所以根本不用这个回调地狱的手法,promise 主要是用来解决异步问题的,由于很多程序员都是同步思考习惯了,异步思起来就挺麻烦,所以代码会出现一套嵌套这一套,当多起来的时候那真的是可以写出一条长龙。先说一个简单应用把,比如图片的预加载,这可以用promise来写,因为图片大小不同,如果一下子全部加载,会出现堵住,第一张图片加载完了之后开始第二张图片加载,promise就是干这个事情的,“你好了没有?好了就到我了”)
-
promise是什么:是一个对象用来传递异步操作的信息,它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的api,可供进一步的处理。
-
promise的作用:Promise的出现主要是解决地狱回调的问题,比如你需要结果需要请求很多个接口,这些接口的参数需要另外那个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有了Promise 我们就无需嵌套。
-
promise的本质是什么:分离异步数据获取和业务
可能大家对interceptor(拦截器)并不是很熟悉,在这里作下介绍,拦截器可以在请求发送前和发送请求后做一些处理。有一张图可以清晰的了解它在一次HTTP请求中做了什么,如下图
拦截器
在请求或响应被 then 或 catch 处理前拦截它们(拦截器可以做什么:在请求或者响应时拦截下来进行处理)
拦截器分为请求拦截器和响应拦截器
- 请求拦截器(interceptors.requst)是指可以拦截每次或指定HTTP请求,并可修改配置项。
- 响应拦截器(interceptors.response)可以在每次HTTP请求后拦截住每次或指定HTTP请求,并可修改返回结果项。
1.3 axios常用语法
- axios(config):通用/最本质的发任意类型请求的方式
- axios(url[, config]):可以只指定url发get 请求
- axios.request(config):等同于axios(config)
- axios.get(url[, config]):发get请求
- axios.delete(url[, config]):发delete请求
- axios.post(url[, data, config]):发post请求
- axios.put(url[, data, configl):发put 请求
- axios.defaults.xxx:请求的默认全局配置
- axios.interceptors.request.use():添加请求拦截器
- axios.interceptors.response.use():添加响应拦截器
- axios.create([config]):创建一个新的axios(它没有下面的功能)
- axios.Cancel():用于创建取消请求的错误对象
- axios.CancelToken():用于创建取消请求的token对象
- axios.isCancel():是否是一个取消请求的错误
- axios.all(promises):用于批量执行多个异步请求
- axios.spread():用来指定接收所有成功数据的回调函数的方法
二 axios的安装
- 1、利用npm安装(例如vue脚手架项目中使用)
npm install axios
- 2、利用cdn(常用)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
- 基本使用:
axios发送get请求:
axios.get('url地址', { params: {请求的参数对象}}).then(function(res){
//.then()表示成功的回调
console.log(res.data) //res.data 是服务器返回的数据,会自动转为js对象格式
})
-------------------------------------------------------------------------------------------
axios发送post请求:
axios.post('url地址', {要提交到服务器的数据}).then(function(res){
console.log(res.data) //res.data 是服务器返回的数据
})
-------------------------------------------------------------------------------------------
直接使用axios发起请求:
axios({
method: '请求类型',
url: '请求的URL地址',
data: { POST数据 }, //POST 数据要通过data属性提供
params: { GET参数 } //GET参数要通过params属性提供
}) .then(function(res){
console.log(res.data)
})
- 默认配置:
axios.defaults.method="post" //设置默认的请求类型
axios.defaults.baseURL="XXX" //设置默认url地址
axios.defaults.XXX=XXX //设置XXX的默认配置为XXX
axios({
....
}).then(function(res){
console.log(res.data)
})
三、axios使用
- axios基本使用
//获取按钮
const btns = document.querySelectorAll('button');
//第一个
btns[0].onclick = function () {
//发送 AJAX 请求
axios({
//请求类型
method: 'GET',
//URL
url: 'http://localhost:3000/posts/2',
}).then(response => {
console.log(response);
});
}
//添加一篇新的文章
btns[1].onclick = function () {
//发送 AJAX 请求
axios({
//请求类型
method: 'POST',
//URL
url: 'http://localhost:3000/posts',
//设置请求体
data: {
title: "今天天气不错, 还挺风和日丽的",
author: "张三"
}
}).then(response => {
console.log(response);
});
}
//更新数据
btns[2].onclick = function () {
//发送 AJAX 请求
axios({
//请求类型
method: 'PUT',
//URL
url: 'http://localhost:3000/posts/3',
//设置请求体
data: {
title: "今天天气不错, 还挺风和日丽的",
author: "李四"
}
}).then(response => {
console.log(response);
});
}
//删除数据
btns[3].onclick = function () {
//发送 AJAX 请求
axios({
//请求类型
method: 'delete',
//URL
url: 'http://localhost:3000/posts/3',
}).then(response => {
console.log(response);
});
}
- axios其他使用:
//获取按钮
const btns = document.querySelectorAll('button');
//发送 GET 请求
btns[0].onclick = function () {
// axios()
axios.request({
method: 'GET',
url: 'http://localhost:3000/comments'
}).then(response => {
console.log(response);
})
}
//发送 POST 请求
btns[1].onclick = function () {
// axios()
axios.post(
'http://localhost:3000/comments',
{
"body": "喜大普奔",
"postId": 2
}).then(response => {
console.log(response);
})
}
- axios默认配置:
//获取按钮
const btns = document.querySelectorAll('button');
//默认配置
axios.defaults.method = 'GET';//设置默认的请求类型为 GET
axios.defaults.baseURL = 'http://localhost:3000';//设置基础 URL
axios.defaults.params = { id: 100 };
axios.defaults.timeout = 3000;//
btns[0].onclick = function () {
axios({
url: '/posts'
}).then(response => {
console.log(response);
})
}
3.1、难点语法的理解和使用
axios.create(config)
- 根据指定配置创建一个新的axios,也就是每个新axios都有自己的配置
- 新axios 只是没有取消请求和批量发请求的方法,其它所有语法都是一致的
- 为什么要设计这个语法?
- (1)需求:项目中有部分接口需要的配置与另一部分接口需要的配置不太一 样,如何处理
- (2)解决:创建2个新axios,每个都有自己特有的配置,分别应用到不同要 求的接口请求中
拦截器函数/ajax请求/请求的回调函数的调用顺序
- 说明:调用axios()并不是立即发送ajax请求,而是需要经历一个较长的流程
- 流程:请求拦截器2=>请求拦截器1=>发ajax请求=>响应拦截器1=>响 应拦截器2=>请求的回调 (unshift,push)
- 注意:此流程是通过promise串连起来的,请求拦截器传递的是config,响应 拦截器传递的是response
// Promise
// 设置请求拦截器 config 配置对象
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 1号');
//修改 config 中的参数
config.params = { a: 100 };
return config;
}, function (error) {
console.log('请求拦截器 失败 - 1号');
return Promise.reject(error);
});
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 2号');
//修改 config 中的参数
config.timeout = 2000;
return config;
}, function (error) {
console.log('请求拦截器 失败 - 2号');
return Promise.reject(error);
});
// 设置响应拦截器
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 1号');
return response.data;
// return response;
}, function (error) {
console.log('响应拦截器 失败 1号')
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 2号')
return response;
}, function (error) {
console.log('响应拦截器 失败 2号')
return Promise.reject(error);
});
//发送请求
axios({
method: 'GET',
url: 'http://localhost:3000/posts'
}).then(response => {
console.log('自定义回调处理成功的结果');
console.log(response);
});
取消请求
- 基本流程
- 配置cancelToken对象
- 缓存用于取消请求的cancel函数
- 在后面特定时机调用cancel函数取消请求
- 在错误回调中判断如果error是cancel,做相应处理
- 实现功能
- 点击按钮,取消某个正在请求中的请求
//获取按钮
const btns = document.querySelectorAll('button');
//2.声明全局变量
let cancel = null;
//发送请求
btns[0].onclick = function () {
//检测上一次的请求是否已经完成
if (cancel !== null) {
//取消上一次的请求
cancel();
}
axios({
method: 'GET',
url: 'http://localhost:3000/posts',
//1. 添加配置对象的属性
cancelToken: new axios.CancelToken(function (c) {
//3. 将 c 的值赋值给 cancel
cancel = c;
})
}).then(response => {
console.log(response);
//将 cancel 的值初始化
cancel = null;
})
}
//绑定第二个事件取消请求
btns[1].onclick = function () {
cancel();
}
响应结构(response对象)
{
// 请求配置信息, 包括url,method等
config: {},
// 响应体数据
data: {},
// http 响应头信息
// 所有的 header 名称都是小写,而且可以使用方括号语法访问
// 例如: response.headers[content-type']
headers: {},
// 原生ajax请求的 XMLHttpRequest 实例
request: {}
// http 请求响应状态码
status: 200,
// 自服务器响应的 HTTP 请求的状态信息
statusText: 'OK',
}
请求配置对象config,就是我们在调用axios的方法的时候传入的对象
{
// `url` 是用于请求的服务器 URL 地址
url: '/user',
// `method` 是创建请求时使用的方法,如果没有method属性,将默认使用get请求
method: 'get', // 默认值
/*baseURL 将自动加在 url 前面,除非 url 是一个绝对 URL。
它可以通过设置一个 baseURL 便于为 axios 实例的方法传递相对 URL,这样可以简化书写
*/
baseURL: 'https://some-domain.com/api/',
// transformRequest 允许在向服务器发送前,修改请求数据
// 它只能用于 PUT, POST 和 PATCH 这几个请求方法
// 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream
// 你可以修改请求头。
transformRequest: [function (data, headers) {
// 对发送的 data 进行任意转换处理
return data;
}],
// transformResponse 在传递给 then/catch 前,允许修改响应数据
transformResponse: [function (data) {
// 对接收的 data 进行任意转换处理
return data;
}],
// 自定义请求头
headers: {'X-Requested-With': 'XMLHttpRequest'},
// params 是与请求一起发送的 URL 参数, 比较常用
// 必须是一个简单对象或 URLSearchParams 对象
//可以简化get请求url的书写:http://xxxxx?a=100&b=200
params: {
a: 100,
b: 200
},
// paramsSerializer 是可选方法,主要用于序列化 params, 使用相对较少
//主要为了应对服务器对于传递参数的要求,比如服务器可能要求 ?a.100/b.200 这样传递参数,这是就需要在函数中配置参数格式与服务器统一
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
// data 是作为请求体被发送的数据
// 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法
// 在没有设置 `transformRequest` 时,则必须是以下类型之一:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 浏览器专属: FormData, File, Blob
// - Node 专属: Stream, Buffer
// 如果是对象格式,axios会转换成json格式字符串传递,如果是字符串格式则直接传递
data: {
firstName: 'Fred'
},
// 发送请求体数据的可选语法
// 请求方式 post
// 只有 value 会被发送,key 则不会
data: 'Country=Brasil&City=Belo Horizonte',
// `timeout` 指定请求超时的毫秒数。
// 如果请求时间超过 `timeout` 的值,则请求会被中断
timeout: 1000, // 默认值是 `0` (永不超时)
// `withCredentials` 表示跨域请求时是否需要使用凭证, false表示不使用
withCredentials: false, // default
// `adapter` 允许自定义处理请求,这使测试更加容易。
// 返回一个 promise 并提供一个有效的响应
adapter: function (config) {
/* ... */
},
// `auth` HTTP Basic Auth
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// `responseType` 表示浏览器将要响应的数据类型
// 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
// 浏览器专属:'blob'
responseType: 'json', // 默认值
// `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
// 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
// Note: Ignored for `responseType` of 'stream' or client-side requests
responseEncoding: 'utf8', // 默认值
// `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
xsrfCookieName: 'XSRF-TOKEN', // 默认值
// `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值
// `onUploadProgress` 允许为上传处理进度事件
// 浏览器专属
onUploadProgress: function (progressEvent) {
// 处理原生进度事件
},
// `onDownloadProgress` 允许为下载处理进度事件
// 浏览器专属
onDownloadProgress: function (progressEvent) {
// 处理原生进度事件
},
// `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
maxContentLength: 2000,
// `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
maxBodyLength: 2000,
// `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。
// 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),
// 则promise 将会 resolved,否则是 rejected。
// 说白了就是怎么认定请求是成功的
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认值
},
// `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
// 如果设置为0,则不会进行重定向
maxRedirects: 5, // 默认值
// `socketPath` 定义了在node.js中使用的UNIX套接字。
// e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
// 只能指定 `socketPath` 或 `proxy` 。
// 若都指定,这使用 `socketPath` 。
socketPath: null, // default
// `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
// and https requests, respectively, in node.js. This allows options to be added like
// `keepAlive` that are not enabled by default.
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
// `proxy` 定义了代理服务器的主机名,端口和协议。
// 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
// 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
// `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
// 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
// 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
proxy: {
protocol: 'https',
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
},
// see https://axios-http.com/zh/docs/cancellation
cancelToken: new CancelToken(function (cancel) {
}),
// `decompress` indicates whether or not the response body should be decompressed
// automatically. If set to `true` will also remove the 'content-encoding' header
// from the responses objects of all decompressed responses
// - Node only (XHR cannot turn off decompression)
decompress: true // 默认值
}
参考: https://blog.csdn.net/ASHIYI66/article/details/127956515
https://blog.csdn.net/whl0071/article/details/126622940