axios(兒個煞斯)是什么?
- 前端最流行的ajax請求庫
- react/vue 官方都推薦使用axios發ajax請求
- 文檔:http://www.axios-js.com/zh-cn/docs/
axios特點
- 基本promise的異步ajax請求庫
- 瀏覽器端/node端都可以使用
- 支持請求/響應攔截器
- 支持請求取消
- 請求/響應數據轉換
- 批量發送多個請求
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,config]) | 發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.create(config)
- 根據指定配置創建一個新的axios, 也就就每個新axios 都有自己的配置
- 新axios 只是沒有取消請求和批量發請求的方法, 其它所有語法都是一致的
- 為什么要設計這個語法?
(1) 需求: 項目中有部分接口需要的配置與另一部分接口需要的配置不太一
樣, 如何處理
(2) 解決: 創建2 個新axios, 每個都有自己特有的配置, 分別應用到不同要
求的接口請求中
攔截器函數/ajax請求/請求的回調函數的調用順序
- 說明: 調用axios()並不是立即發送ajax 請求, 而是需要經歷一個較長的流程
- 流程: 請求攔截器2 => 請求攔截器1 => 發ajax 請求=> 響應攔截器1 => 響
應攔截器2 => 請求的回調 - 注意: 此流程是通過promise 串連起來的, 請求攔截器傳遞的是config, 響應
攔截器傳遞的是response
取消請求
- 基本流程
配置cancelToken 對象
緩存用於取消請求的cancel 函數
在后面特定時機調用cancel 函數取消請求
在錯誤回調中判斷如果error 是cancel, 做相應處理 - 實現功能
點擊按鈕, 取消某個正在請求中的請求
在請求一個接口前, 取消前面一個未完成的請求
axios的使用
發送axios請求
<body>
<div>
<button onclick="testGet()">GET請求</button>
<button onclick="testPost()">POST請求</button>
<button onclick="testPut()">PUT請求</button>
<button onclick="testDelete()">DELETE請求</button>
</div>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
<script>
// 指定默認配置
axios.defaults.baseURL = 'http://localhost:3000'
/* 1. GET請求: 從服務器端獲取數據*/
function testGet() {
// axios.get('/posts?id=1')
axios({
url: '/posts',
params: {
id: 1
}
})
.then(response => {
console.log('/posts get', response.data)
})
}
/* 2. POST請求: 向服務器端添加新數據*/
function testPost() {
// axios.post('/posts', {"title": "json-server3", "author": "typicode3"})
axios({
url: '/posts',
method: 'post',
data: {"title": "json-server4", "author": "typicode4"}
})
.then(response => {
console.log('/posts post', response.data)
})
}
/* 3. PUT請求: 更新服務器端已經數據 */
function testPut() {
// axios.put('http://localhost:3000/posts/4', {"title": "json-server...", "author": "typicode..."})
axios({
url: '/posts/4',
method: 'put',
data: {"title": "json-server5", "author": "typicode5"}
})
.then(response => {
console.log('/posts put', response.data)
})
}
/* 4. DELETE請求: 刪除服務器端數據 */
function testDelete() {
// axios.delete('http://localhost:3000/posts/4')
axios({
url: '/posts/5',
method: 'delete'
})
.then(response => {
console.log('/posts delete', response.data)
})
}
</script>
</body>
create方法
需求: 項目中有部分接口需要的配置與另一部分接口需要的配置不太一樣, 如何處理
解決: 創建2個新axios, 每個都有自己特有的配置, 分別應用到不同要求的接口請求中
<body>
<!--
1). axios.create(config)
a. 根據指定配置創建一個新的axios, 也就就每個新axios都有自己的配置
b. 新axios只是沒有取消請求和批量發請求的方法, 其它所有語法都是一致的
c. 為什么要設計這個語法?
需求: 項目中有部分接口需要的配置與另一部分接口需要的配置不太一樣, 如何處理
解決: 創建2個新axios, 每個都有自己特有的配置, 分別應用到不同要求的接口請求中
-->
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
<script>
axios.defaults.baseURL = 'http://localhost:3000'
// 使用axios發請求
axios({
url: '/posts' // 請求3000
})
// axios({
// url: '/xxx' // 請求4000
// })
const instance = axios.create({
baseURL: 'http://localhost:4000'
})
// 使用instance發請求
// instance({
// url: '/xxx' // 請求4000
// })
instance.get('/xxx')
</script>
</body>
axios的處理鏈流程
// 添加請求攔截器(回調函數)
axios.interceptors.request.use(
config => {
console.log('request interceptor1 onResolved()')
return config
},
error => {
console.log('request interceptor1 onRejected()')
return Promise.reject(error);
}
)
axios.interceptors.request.use(
config => {
console.log('request interceptor2 onResolved()')
return config
},
error => {
console.log('request interceptor2 onRejected()')
return Promise.reject(error);
}
)
// 添加響應攔截器
axios.interceptors.response.use(
response => {
console.log('response interceptor1 onResolved()')
return response
},
function (error) {
console.log('response interceptor1 onRejected()')
return Promise.reject(error);
}
)
axios.interceptors.response.use(
response => {
console.log('response interceptor2 onResolved()')
return response
},
function (error) {
console.log('response interceptor2 onRejected()')
return Promise.reject(error);
}
)
axios.get('http://localhost:3000/posts')
.then(response => {
console.log('data', response.data)
})
.catch(error => {
console.log('error', error.message)
})
取消請求
<body>
<button onclick="getProducts1()">獲取商品列表1</button><br>
<button onclick="getProducts2()">獲取商品列表2</button><br>
<button onclick="cancelReq()">取消請求</button><br>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
<script>
let cancel // 用於保存取消請求的函數
function getProducts1() {
axios({
url: 'http://localhost:4000/products1',
cancelToken: new axios.CancelToken((c) => { // c是用於取消當前請求的函數
// 保存取消函數, 用於之后可能需要取消當前請求
cancel = c
})
}).then(
response => {
cancel = null
console.log('請求1成功了', response.data)
},
error => {
cancel = null
console.log('請求1失敗了', error.message, error)
}
)
}
function getProducts2() {
axios({
url: 'http://localhost:4000/products2'
}).then(
response => {
console.log('請求2成功了', response.data)
},
error => {
cancel = null
console.log('請求2失敗了', error.message)
}
)
}
function cancelReq() {
// alert('取消請求')
// 執行取消請求的函數
if (typeof cancel === 'function') {
cancel('強制取消請求')
} else {
console.log('沒有可取消的請求')
}
}
</script>
</body>