axios 的理解和使用 axios.create(對axios請求進行二次封裝) 攔截器 取消請求(axios.CancelToken)
axios是什么
- 前端最流行的 ajax請求庫
- react/vue官方推薦使用axios發ajax請求
- 文檔 https://github.com/axios/axios
axios特點
- 基於promise的異步ajax請求庫
- 瀏覽器端/node端都可以使用
- 支持請求/響應攔截器
- 支持請求取消
- 請求/響應數據轉換
- 批量發送多個請求
axios常用語法
nam | value |
---|---|
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(promise) | 用於批量執行多個異步請求 |
axios安裝
npm install axios
- 1
vue項目使用
在main.js
import axios from 'axios'
Vue.prototype.$ajax = axios
- 1
- 2
html 直接導入就行了
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
- 1
axios簡單使用
默認get請求
// 配置默認基本路徑
axios.defaults.baseURL = 'http://localhost:3000'
// 默認get請求
axios({
url:"/posts",
params:{
id:1
}
}).then(res=>{
console.log(res)
},err=>{
console.log(err)
})
post
// post請求
axios.post("/posts",{id:1}).then(res=>{
console.log(res)
},err=>{
console.log(err)
})
// 或
axios({
url:"/posts",
method:'post'
data:{
id:1
}
}).then(res=>{
console.log(res)
},err=>{
console.log(err)
})
put
axios.put("/posts/4",{
"title": "json-server---1",
"author": "typicode",
}).then(res=>{
console.log(res)
},err=>{
console.log(err)
})
// 或
axios({
url:"/posts",
method:'put '
data:{
"title": "json-server---1",
"author": "typicode",
}
}).then(res=>{
console.log(res)
},err=>{
console.log(err)
})
delete
axios.delete("/posts/4",{
"title": "json-server---1",
"author": "typicode",
}).then(res=>{
console.log(res)
},err=>{
console.log(err)
})
// 或
axios({
url:"/posts",
method:'delete'
data:{
id:1
}
}).then(res=>{
console.log(res)
},err=>{
console.log(err)
})
axios難點語法
axios.create(config) 對axios請求進行二次封裝
- 根據指定配置創建一個新的 axios ,也就是每個axios 都有自己的配置
- 新的 axios 只是沒有 取消請求 和 批量請求 的方法,其它所有語法都是一致的
- 為什么要這種語法?
- 需求,項目中有部分接口需要的配置與另一部分接口的配置不太一樣
- 解決:創建2個新的 axios ,每個都有自己的配置,分別對應不同要求的接口請求中
簡單使用
const instance = axios.create({
baseURL:"http://localhost:3000"
})
// 使用instance發請求
instance({
url:"/posts"
})
// 或
instance.get("/posts")
同時請求 多個端口號
const instance = axios.create({
baseURL:"http://localhost:3000"
})
const instance2 = axios.create({
baseURL:"http://localhost:4000"
})
// 同時請求 端口號 3000 4000
// 使用instance發請求
instance({
url:"/posts"
})
// 使用instance2發請求
instance2({
url:"/posts"
})
axios的處理鏈流程 攔截器
攔截器簡單使用
// 添加請求攔截器
axios.interceptors.request.use(config=>{
// config 請求配置
console.log("請求攔截器")
return config
},err=>{
return Promise.reject(err)
})
// 添加響應攔截器
axios.interceptors.response.use(res=>{
// res 響應結果
console.log("響應攔截器")
return res
},err=>{
return Promise.reject(err)
})
console.log("開始請求")
axios.get("http://localhost:3000/posts")
.then(res=>{
console.log("res:",res)
console.log("請求結束")
})
多個攔截器
請求攔截器后添加先執行
// 添加請求攔截器
axios.interceptors.request.use(config=>{
console.log("請求攔截器")
return config
},err=>{
return Promise.reject(err)
})
axios.interceptors.request.use(config=>{
console.log("請求攔截器--------2")
return config
},err=>{
return Promise.reject(err)
})
axios.interceptors.request.use(config=>{
console.log("請求攔截器--------3")
return config
},err=>{
return Promise.reject(err)
})
// 添加響應攔截器
axios.interceptors.response.use(res=>{
console.log("響應攔截器")
return res
},err=>{
return Promise.reject(err)
})
axios.interceptors.response.use(res=>{
console.log("響應攔截器---------2")
return res
},err=>{
return Promise.reject(err)
})
axios.interceptors.response.use(res=>{
console.log("響應攔截器----------3")
return res
},err=>{
return Promise.reject(err)
})
console.log("開始請求")
axios.get("http://localhost:3000/posts")
.then(res=>{
console.log("res:",res)
console.log("請求結束")
})
取消請求
1. 基本流程
配置 cancelToken 對象
緩存用於取消請求的 cancel 函數
在后面特定時機調用 cancel 函數取消請求
在錯誤回調中判斷如果 error 是cancel ,做相應處理
- 1
- 2
- 3
- 4
2. 實現功能
node運行server.js
安裝node和express (npm install express)
var http = require("http");
var express = require("express")
// var server = http.createServer();
var app = express()
// node跨域設置
app.all("*",function(req,res,next){
//設置允許跨域的域名,*代表允許任意域名跨域
res.header("Access-Control-Allow-Origin","*");
//允許的header類型
res.header("Access-Control-Allow-Headers","content-type");
//跨域允許的請求方式
res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
if (req.method.toLowerCase() == 'options')
res.send(200); //讓options嘗試請求快速結束
else
next();
})
app.get('/',function(res,req){
console.log("獲取客戶端請求",res);
// 延遲響應 方便測試取消接口
setTimeout(function(){
req.end("延遲響應 方便測試取消接口"); //響應客戶數據
},5000)
})
app.listen(4000,function(){
console.log("服務器啟動成功,可以通過 http://127.0.0.1:4000 進行訪問")
})
在cmd窗口
node server.js
- 1
調用接口測試
axios.isCancel(err) //判斷錯誤是否 是取消請求導致的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
</head>
<body>
<script>
let cancel;
// axios({
// url:"http://localhost:4000",
// cancelToken:new axios.CancelToken(function(c){
// cancel = c
// })
// })
// 或
axios.get("http://localhost:4000",{
cancelToken:new axios.CancelToken(function(c){
// c 用於取消當前請求的函數
cancel = c
})
})
.then(res=>{
console.log("res:",res)
cancel = null //請求完成,清空cancel
},err=>{
cancel = null
if(err.constructor.name === 'Cancel'){ //是取消請求導致的errer
console.log("取消請求導致error:",err)
}else{
console.log("err:",err)
}
// 或
// axios.isCancel(err) //判斷錯誤是否 是取消請求導致的
});
setTimeout(function(){
if(typeof(cancel) === 'function'){
cancel('強制取消了請求')
}else{
console.log("沒有可取消的請求")
}
},2000)
</script>
</body>
</html>
正常請求
取消接口
在 請求攔截器里面統一添加取消請求
axios.interceptors.request.use(res=>{
res['cancelToken'] = new axios.CancelToken(function(c){
cancel = c
})
return res
},err=>{
return Promise.reject(err)
})
在 響應攔截器里面統一添加 處理取消請求
axios.interceptors.response.use(res=>{
return res
},err=>{
if(axios.isCancel(err)){
// 中斷promise鏈接
return new Promise(()=>{})
}else{
// 把錯誤繼續向下傳遞
return Promise.reject(err)
}
})
代碼簡化 實現上一個接口還未響應 下一個接口開始請求,把上一個接口取消
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.js"></script>
</head>
<body>
<script>
let cancel;
axios.interceptors.request.use(config=>{
// 實現上一個接口還未響應 下一個接口開始請求,把上一個接口取消
if(typeof(cancel) === 'function'){
cancel('強制取消了請求')
}
config['cancelToken'] = new axios.CancelToken(function(c){
cancel = c
})
return config
},err=>{
return Promise.reject(err)
})
axios.interceptors.response.use(res=>{
cancel = null
return res
},err=>{
cancel = null
if(axios.isCancel(err)){
console.log("取消上一個請求")
// 中斷promise鏈接
return new Promise(()=>{})
}else{
// 把錯誤繼續向下傳遞
return Promise.reject(err)
}
})
function request(){
axios.get("http://localhost:4000")
.then(res=>{
console.log("res:",res)
},err=>{
console.log("err:",err)
});
}
request()
request()
</script>
</body>
</html>