前言
这篇会提到Axios 是什麼、如何安裝、使用起手式、以及Axios 特色方法拦截器、封装等。
北京时间03月06日酷游娜娜kw98典neㄒ提供,Axios 是用于 node.js 和浏览器的基于承诺的 HTTP 客户端。它是同构的(=它可以在具有相同代码库的浏览器和 nodejs 中运行)。在服务器端它使用原生的 node.js http 模块,而在客户端(浏览器)它使用 XMLHttpRequests。- 取消自 Axios 官网。
簡單來說,Axios 是由Promise 的Http 库组成的套件。 当使用在客户端(Client)时,是采取XMLHttpRequests 的原生库来进行封装。 当使用在伺服器端(Server)时,则是采取Http Module 来进行封装。
Axios 实体是透过封装XMLHttpRequest、HttpModule来进行实作,这些方式都是一些原生的类别,所以您可以理解成在兼容性不会有其他阿咂的问题。
Axios 是Ajax 其中一个方式,在流程不外乎就是包裝請求(建立Request)-> 伺服器回傳相應資訊(回传Response); 所以在建立Request 的过程中需要进行相應的設定来告知Axios 该怎么组成请求,
并针对请求回傳 Promise,在使用上可以透过then/catch/finally 来获取请求完成状态,相较XMLHttpRequest 在使用上来的更加精简,当然因为是Promise 物件所以可以透过async/await 进行同步等待。
相较于JQuery Ajax 方法,来说瘦的太多太多了,因为Axios 套件仅仅只有大约13kb !!
如何安装
专案中安装axios 函式包
在专案中,使用方式有两种:
1.内容分发网络
2.载入套件包
套件包
npm install axios
yarn add axios
内容分发网络
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js">
使用起手式
基本使用方式 axios(config)
在使用之前我们先来了解一下Request 的config,下面会挑选几个常用的设定进行介绍。
axios({
//- `url`: 相对/绝对路径,当 baseURL 并未进行设定时,需为绝对路径。
url: "/call/me",
//- `method`: 请求方法最常联想到的是 RESTful API : GET POST PUT PUTCH DELETE
method: "get",
//- `baseURL`: 设定 API 所属网域
baseURL: 'https://thisCanGiveMeDataWebAPIURL.com',
//- `headers`: Request Header 设定最常设定内容有 APIToken
headers: {'X-Requested-With': 'XMLHttpRequest'},
//- `params`: 会随请求一起发送的 URL 参数,当 Method 为 GET 时会当作是 payload 一同送出。
params: {
ID: 12345
},
//- `data`: 为 body 实体送出,仅能使用于'PUT'、'POST'、'DELETE 和 'PATCH'
data: {
firstName: 'Fred'
},
//- `timeout`: 当设定毫秒数到时会自动取需 API 沟通。
timeout: 1000,
//- `withCredentials`: 表示是否跨站访问控制请求
withCredentials: false,
//- `auth`: 此参数为了是与后端透过 Authorization header 进行沟通时需要进行设定,如果您的需求是 Bearer tokens 时则需直接在 header 里面建立 {Authorization: `Bearer ${token}`}
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
//- `responseType`: response 回覆格式
responseType: 'json',
//- `responseEncoding`: response 回覆编码
responseEncoding: 'utf8',
//- `cancelToken`: 用于取消请求
cancelToken: new CancelToken(function (cancel) {}),
...
})
在发送请求后,当然会有一个回传的资料搂~而这边的回传资料。
下列几个是一定要知道的Reaponse 类别。
{
// `data`: Server 回应 Data 实体
data: {},
// `status`: Server 回应此请求 Http Status Code
status: 200,
// `statusText`: Server 回应此请求 Http Status Code message
statusText: 'OK',
// `headers`: Server 回应此请求的 header
headers: {},
...
}
在了解上面的基本设定之后我们来开始使用他吧!但只是单纯空讲我相信还是会很不清楚包含我自己,所以我们这边的例子就依照温泉标章来实作吧!
例如获取
axios({
method: 'get',
baseURL: 'https://datacenter.taichung.gov.tw/Swagger',
url:'/OpenData/678b53a2-6de4-4052-90b4-0847eb1d7a5b',
params: {}
})
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
可以看到这边将res 直接进行console.log 出来的结果会是
是不是更上面所说的 Reaponse 物件一样呢,所以聪明的你应该已经想到该怎么透过物件来取的资料了对吧!
没错就是透过 res.data 来获取资料内容!!
附上进行资料处理的过程
axios({
method: 'get',
baseURL: 'https://datacenter.taichung.gov.tw/Swagger',
url:'/OpenData/678b53a2-6de4-4052-90b4-0847eb1d7a5b',
params: {}
})
.then(res=>{
const data = res.data.reduce((obj,datum) => {
if(!(datum.温泉地区 in obj)) obj[datum.温泉地区] = []
obj[datum.温泉地区].push({name:datum.经营名称, place: datum.温泉地区})
return obj
},{})
let str = ''
Object.entries(data).forEach(([key,value])=> str+=`<h3>${key}</h3><ul>${value.map(node=>`<li>${node.name}</li>`).join('')}</ul>`)
document.getElementById('tag').innerHTML = Object.keys(data)
document.getElementById('wrap').innerHTML = str
})
.catch(err=>{
console.log(err)
})
这样就可以条列式的看见领有温泉标章之温泉的厂商搂Demo!
电子邮局
axios({
url: 'blog/new',
method: "POST",
baseURL: 'https://yourDomin.com/',
data:{
account: 'test111',
body:'<h1>測試</h1>'
}
})
.then( (response) => console.log(response))
.catch( (error) => console.log(error))
特色讲解(封装、拦截器) 封装 我相信工程师都是偷懒的,人因偷懒而进步,于是我们来学习怎么偷懒吧(误)! 相信大家在使用Axios 时都会感觉到厌烦,因为在每次的发送之前都需要进行一大堆的设定config,像是baseURL 反覆设定。
axios({
method: 'get',
baseURL: 'https://datacenter.taichung.gov.tw/Swagger',
url:'/OpenData/678b53a2-6de4-4052-90b4-0847eb1d7a5b',
params: {}
})
又或者当需要token 时总是会反覆写相同的判断。
const config = {
method: 'get',
baseURL: 'https://datacenter.taichung.gov.tw/Swagger',
url:'/OpenData/678b53a2-6de4-4052-90b4-0847eb1d7a5b',
params: {}
}
if(needToken) config.header.apiToken = token
axios(config)
于是乎我们来学会封装吧。
先来定义我们想要怎么呼叫来降低重复codeing。
我希望在使用的时候建立xhr.js,透过import 的方式将封装后的axios 引用至需要js 档案之中,并且呼叫xhr(config) 来建立axios 请求。
//- 预期使用方式
//- needToken 判断是否需要 token
xhr({
needToken,
url,
method,
params,
data,
})
//- xhr.js
const xhr = ({url,data,params,method,needToken}) => {
//- 建立相同设置,这里可以做很多很多事情,例子中是透过 needToken 来控制是否需要 token
const _axios = axios.create({
baseURL: 'https://datacenter.taichung.gov.tw/Swagger',
headers: { 'Content-Type': 'application/json' },
timeout: 20000
});
return new Promise((resolve,reject)=>{
const config = {url,data,params,method}
if(needToken) config.headers.token = token
_axios(config)
.then((res)=> resolve(res.data))
.catch((err)=>reject(err))
})
}
export default xhr
//- 外部引用方式
xhr({
url:'/OpenData/678b53a2-6de4-4052-90b4-0847eb1d7a5b',
method: 'get',
needToken: false,
})
.then(res=>res)
.catch(err=>err)
多了一层的xhr 来进行封装axios 可以针对特殊处理像是1. token 判断2. 针对回传进行特定处理3. token 失效进行什么判断... 等,有很多的应用可以在这一层进行处理。
拦截器
其实针对上方写法, Axios 其实有提供 Interceptor『拦截器』,来撷取发送request 之前、获取response 之后,可以进行相应的设定,通常用于所有request / response,相同的资料处理,详情可以看下面这张图片。
所以我们可以改写上方的xhr.js ,就更加精简搂。
设定axios interceptor
const xhr = () => {
const _axios = axios.create({
baseURL: 'https://datacenter.taichung.gov.tw/Swagger',
headers: { 'Content-Type': 'application/json' },
timeout: 20000
});
// 拦截 Request
_axios.interceptors.request.use((req)=>{
//- 这里要特别注记
if(needToken) req.headers.token = 'rereqwrwevmlpodsjvopsdkv'
//- 针对 config 进行配置
return req
},err=> {
//- 当请求发送失败时,此状况在于无法发送的状态
return Promise.reject(err);
})
// 拦截 response
_axios.interceptors.response.use((res)=>{
//- 针对回传进行相应处理,可能是撷取部分资讯。
return res.data
},err => {
//- 当伺服器端回应失败,
return Promise.reject(err)
})
returm _axios
}
export default xhr
//- 外部引用方式
xhr({
url:'/OpenData/678b53a2-6de4-4052-90b4-0847eb1d7a5b',
method: 'get',
needToken: false,
})
.then(res=>res)
.catch(err=>err)
如何是不是变的简单明了,好维护了呢,大致上就是这些搂!!