安裝 axios
-
npm
$ npm install --save axios
-
cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
使用方式
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios 特點
- 基本 Promise 的異步 AJAX 請求庫 (封裝 XHR)
- 瀏覽器端與 NodeJS 端都可以使用
- 支援 Request 與 Response 的攔截
- 支援取消 Request
- Request 與 Response 的資料轉換 (轉為 JSON)
- 批量發送多個 Request
axios 常用語法
- axios(config)
- axios(url[, config])
- 指定用 GET 發送 Request
- axios.request(config)
- 等同於 axios(config)
- axios.get(url[, config])
- axios.post(url[, config])
- axios.put(url[, config])
- axios.delete(url[, config])
- axios.defaults.xxx
- 全域配置
- axios.interceptors.request.use()
- axios.interceptors.response.use()
- axios.create([config])
- axios.Cancel()
- 取消 Request
- axios.CancelToken()
- 取消 Request 的 Token 物件
- axios.isCancel()
- 是否為一個取消 Request 的錯誤
- axios.all(promises)
- 用來批量執行多個異步 Request
- axios.spread()
- 用來指定接收所有成功資料的 callback
config
const config = {
url: "/users", // 必填
method: "post", // 大小寫皆可,預設是 get
headers: { "Content-Type": "application/json" },
baseURL: "http://localhost:3000", // 會自動加在 url 前面,除非 url 為絕對路徑
timeout: 1000,
data: { name: "test", title: 777 },
params: { ID: 123 },
// paramsSerializer 是一个負責 params 序列化的函数
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function(params) {
return Qs.stringify(params, { arrayFormat: "brackets" });
},
// transformRequest 允許在發請求前,修改 Request 資料
// 只能用在 'PUT', 'POST' 和 'PATCH'
// 後面陣列中的函數必须回傳一个字符或 ArrayBuffer 或 Stream
transformRequest: [
function(data) {
// 對 data 進行任意轉換
return data;
},
],
// transformResponse 在傳给 then/catch 前,可以修改 response 資料
transformResponse: [
function(data) {
// 對 data 進行任意轉換
return data;
},
],
// 伺服器回應的數據類型
// 選項: 'arraybuffer', 'document', 'json', 'text', 'stream'
// 瀏覽器才有 'blob',預設為 'json'
responseType: "json",
// 伺服器回應的編碼模式 預設 'utf8'
responseEncoding: "utf8",
// 限制 Response 大小
maxContentLength: 2000,
// 在上傳、下載途中可執行的事情 (progressBar、Loading)
onUploadProgress(progressEvt) {
/* 原生 ProgressEvent */
},
onDownloadProgress(progressEvt) {
/* 原生 ProgressEvent */
},
// xsrfCookieName 是用作 xsrf token 的值的 cookie 的名稱
xsrfCookieName: "XSRF-TOKEN", // default
// xsrfHeaderName 是乘載 xsrf token 的值的 HTTP Header 的名稱
xsrfHeaderName: "X-XSRF-TOKEN", // default
// 允許自定義處理請求,可讓測試更容易
// return promise 並提供有效的回應 (valid response)
adapter(config) {},
// 表示跨域請求時是否需要使用 cookie,預設是 false
withCredentials: false,
// 必須提供 credentials (Cookie)
// 等同 Authorization 表頭
// 如果使用 token 應去 header 設置 Authorization 而非使用此
auth: { username: "Mark", password: 123 },
// 用來判斷是否解析 Promise 的 狀態碼範圍
validateStatus: function(status) {
return status >= 200 && status < 300; // default
},
maxRedirects: 5, // 預設為 5 次
// xsrf token 的 Cookie名 / Header名
xsrfCookieName: "XSRF-TOKEN", // default
xsrfHeaderName: "X-XSRF-TOKEN", // default
// 代理伺服器
proxy: {
host: "127.0.0.1",
port: 9000,
auth: {
username: "mikeymike",
password: "rapunz3l",
},
},
// 用來取消請求的 token
cancelToken: new CancelToken(function(cancel) {}),
};
回傳
{
data: {},
status: 200,
statusText: "OK",
headers: {},
config: {}, // Request 的 config
};
axios.get('/user/12345')
.then(function(response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});
axios.create()
-
創建一個實例
const instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} }); // 程式的某個地方再修改為 instance.defaults.baseURL = 'https://other-domain.com/api/';
-
使用實例的方法
instance.get('/longRequest', { timeout: 5000 });
攔截器
-
新增攔截器
// 新增請求攔截器 axios.interceptors.request.use(function (config) { // 在發請求前做一些事 return config; }, function (error) { // 對失敗的請求做一些事 return Promise.reject(error); }); // 新增回應攔截器 axios.interceptors.response.use(function (response) { // 對回傳值做一些事 return response; }, function (error) { // 對失敗的回應做一些事 return Promise.reject(error); });
-
新增實例的攔截器
var instance = axios.create(); instance.interceptors.request.use(function () {/*...*/});
-
移除攔截器
var myInterceptor = axios.interceptors.request.use(function () {/*...*/}); axios.interceptors.request.eject(myInterceptor);
取消請求
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 處理錯誤
}
});
// 取消請求(message 參數可選)
source.cancel('Operation canceled by the user.');
併發請求 axios.all
- 類似 Promise All 用法
- then 後接 axios.spread
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 兩個請求都完成
}));
模擬實作一個簡易版的 axios
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>模擬 axios</title>
</head>
<body>
<button onclick="testGet()">get</button>
<button onclick="testPost()">post</button>
<button onclick="testPut()">put</button>
<button onclick="testDelete()">delete</button>
<script>
function axios({ url, method = "GET", params = {}, data = {} }) {
method = method || "GET";
method = method.toUpperCase();
let query = [];
Object.keys(params).forEach((key) => {
query.push(`${key}=${params[key]}`);
});
const queryString = query.join("&");
url += `?${queryString}`;
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.responseType = "json";
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) {
return;
}
if (xhr.status >= 200 && xhr.status < 300) {
const response = {
data: xhr.response,
status: xhr.status,
statusText: xhr.statusText,
};
resolve(response);
} else {
reject(
new Error(
"請求失敗 status code = " + xhr.status
)
);
}
};
if (method === "GET" || method === "DELETE") {
xhr.send(null);
} else {
xhr.setRequestHeader(
"Content-Type",
"application/json;charset=utf-8"
);
xhr.send(JSON.stringify(data));
}
});
}
function testGet() {
axios({
url: "http://localhost:3000/users",
// url: "http://localhost:3000/users1",
params: { age: 18, gender: "female" },
})
.then((response) => {
console.log("get 成功", response.data, response);
})
.catch((error) => {
console.log("get 失敗", error.message);
});
}
function testPost() {
axios({
url: "http://localhost:3000/users",
// url: "http://localhost:3000/users1",
method: "POST",
data: { name: "john", age: 30, gender: "male" },
})
.then((response) => {
console.log("post 成功", response.data, response);
})
.catch((error) => {
console.log("post 失敗", error.message);
});
}
function testPut() {
axios({
url: "http://localhost:3000/users/1",
// url: "http://localhost:3000/users1",
method: "PUT",
data: { name: "andy", age: 1, gender: "male" },
})
.then((response) => {
console.log("put 成功", response.data, response);
})
.catch((error) => {
console.log("put 失敗", error.message);
});
}
function testDelete() {
axios({
url: "http://localhost:3000/users/1",
// url: "http://localhost:3000/users1",
method: "DELETE",
})
.then((response) => {
console.log("delete 成功", response.data, response);
})
.catch((error) => {
console.log("delete 失敗", error.message);
});
}
</script>
</body>
</html>