- 從瀏覽器中建立XMLHttpRequests
- 從node.js中建立http請求
- 支持PromiseAPI
- 攔截請求和響應
- 轉換請求數據和響應數據
- 取消請求
- 自動轉化JSON數據
- 客戶端支持防護XSRF
使用npmjava
npm install axios --save
複製代碼
使用cdnnode
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
複製代碼
執行GET請求,當執行GET方式時,若是攜帶請求參數,請求參數能夠有兩種方式:react
axios.get('/user?ID=12121').then((response)=> {
//response
}).catch((error)=> {
//error
});
或者
axios.get('/user',{
params: {
ID: 12121
}
}).then((response)=> {
//response
}).catch((error)=> {
//error
});
複製代碼
執行POST請求jquery
axios.post('/user',{
name: '12121'
}).then((response) => {
//reponse
}).catch((error) => {
//error
});
複製代碼
執行多個併發請求ios
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.get/post這種寫法,這種寫法稍微有點麻煩,能夠經過這種寫法,經過axios傳遞相關配置來建立請求。同時axios的默認的請求方式爲GET方式。npm
axios({
url: apiURL,
method: method,
timeout: timeout,
data: data,
params: params,
headers: {
'Content-Type': 'application/json',
'token': window.sessionStore.getItem('token') || ''
}
});
複製代碼
當處理併發的方式時:json
- axios.all(iterable)
- axios.spread(callback)
語法: axios.create([config])axios
var instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
複製代碼
相關的請求配置c#
這些是建立請求時能夠用的配置選項。只有 url
是必需的。若是沒有指定 method
,請求將默認使用 get
方法。api
//'url'是用於請求服務器的URL
url: '/user',
//'method'是建立請求時使用的方法
method: 'get', //默認是get
//'baseUrl'將自動加在'url'前面,除非'url'是一個絕對url
//它能夠經過設置一個 `baseURL` 便於爲 axios 實例的方法傳遞相對 URL
baseURL: 'https://some-domain.com/api/',
//'transformRequest'容許向服務器發送前,修改請求數據
//只能用在put、post、patch這幾個請求方法
//後面數組中的函數必須返回一個字符串,或ArrayBuffer,或Stream
transformRequest: [function (data){
//對data進行任意轉換處理
return data;
}],
//'transformResponse'在傳遞then/catch前,容許修改響應數據
transformResponse: [function (data){
// 對data進行任意的轉換
return data;
}],
//'headers'是即將被髮送的自定義請求頭
headers: {'X-Requested-With': 'XMLHttpRequest'},
//'params'是即將與請求一塊兒發送的url參數
//必須是一個無格式對象(plain object)或 URLSearchParams對象
params: {
ID: 12345
},
// `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'})
},
// 'data'是做爲請求主體被髮送的數據
// 只適用於這些請求方法(put,post,patch)
// 在沒有設置 `transformRequest` 時,必須是如下類型之一:
// string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - 瀏覽器專屬:FormData, File, Blob
// - Node 專屬: Stream
data: {
name: '1212'
},
// `timeout` 指定請求超時的毫秒數(0 表示無超時時間)
// 若是請求話費了超過 `timeout` 的時間,請求將被中斷
timeout: 1000,
// `withCredentials` 表示跨域請求時是否須要使用憑證
withCredentials: false, // 默認的
// `adapter` 容許自定義處理請求,以使測試更輕鬆
// 返回一個 promise 並應用一個有效的響應 (查閱 [response docs](#response-api)).
adapter: function (config) {
/* ... */
},
// `auth` 表示應該使用 HTTP 基礎驗證,並提供憑據
// 這將設置一個 `Authorization` 頭,覆寫掉現有的任意使用 `headers` 設置的自定義 `Authorization`頭
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// 'responseType'表示服務器響應的數據類型,能夠是arraybuffer,blob,document,json,text,stream
responseType: 'json',
複製代碼
某個請求的響應包含如下信息:
{
// `data` 由服務器提供的響應
data: {},
// `status` 來自服務器響應的 HTTP 狀態碼
status: 200,
// `statusText` 來自服務器響應的 HTTP 狀態信息
statusText: 'OK',
// `headers` 服務器響應的頭
headers: {},
// `config` 是爲請求提供的配置信息
config: {}
}
複製代碼
在實際的開發過程當中後臺的接口會遵循RESTful規範,同時會本身封裝數據的返回格式,例如是下面這種格式:
也就是說咱們取出的數據是從response.data中去拿到,而後按必定的格式取,通常後臺的數據的封裝格式以下:
新建一個util的包:
MessageEntity類:
package com.ssm.util;
import lombok.Data;
@Data
public class MessageEntity<T> {
private Integer code;
private String msg;
private T data;
private Integer total;
}
複製代碼
MessageCode類:
package com.ssm.util;
public enum MessageCode {
SYSTEM_CODE(500, "系統錯誤");
private Integer code;
private String message;
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
MessageCode(Integer code, String message) {
this.code = code;
this.message = message;
}
}
複製代碼
ResultForma類:
package com.ssm.util;
public class ResultFormat {
public static MessageEntity success() {
return success(null);
}
public static <T> MessageEntity<T> success(T t){
MessageEntity msg = new MessageEntity();
msg.setCode(200);
msg.setMsg("操做成功");
msg.setData(t);
return msg;
}
public static MessageEntity error(MessageCode message) {
MessageEntity msg = new MessageEntity();
msg.setCode(message.getCode());
msg.setMsg(message.getMessage());
return msg;
}
}
複製代碼
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
複製代碼
// 建立實例時設置配置的默認值
var instance = axios.create({
baseURL: 'https://api.example.com'
});
// 在實例已建立後修改默認值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
複製代碼
配置會以一個優先順序進行合併。這個順序是:在 lib/defaults.js
找到的庫的默認值,而後是實例的 defaults
屬性,最後是請求的 config
參數。後者將優先於前者。這裏是一個例子:
// 使用由庫提供的配置的默認值來建立實例
// 此時超時配置的默認值是 `0`
var instance = axios.create();
// 覆寫庫的超時默認值
// 如今,在超時前,全部請求都會等待 2.5 秒
instance.defaults.timeout = 2500;
// 爲已知須要花費很長時間的請求覆寫超時設置
instance.get('/longRequest', {
timeout: 5000
});
複製代碼
在請求或響應被 then
或 catch
處理前攔截它們。
// 添加請求攔截器
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 myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
複製代碼
可使用 CancelToken.source
工廠方法建立 cancel token,像這樣:
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下面的lib/axios.js文件
lib/axios.js中代碼建立實例代碼分析:
// lib/axios.js
function createInstance(defaultConfig) {
// 建立一個Axios實例
var context = new Axios(defaultConfig);
// 如下代碼也能夠這樣實現:var instance = Axios.prototype.request.bind(context);
// 這樣instance就指向了request方法,且上下文指向context,因此能夠直接以 instance(option) 方式調用
// Axios.prototype.request 內對第一個參數的數據類型判斷,使咱們可以以 instance(url, option) 方式調用
var instance = bind(Axios.prototype.request, context);
// 把Axios.prototype上的方法擴展到instance對象上,
// 這樣 instance 就有了 get、post、put等方法
// 並指定上下文爲context,這樣執行Axios原型鏈上的方法時,this會指向context
utils.extend(instance, Axios.prototype, context);
// 把context對象上的自身屬性和方法擴展到instance上
// 注:由於extend內部使用的forEach方法對對象作for in 遍歷時,只遍歷對象自己的屬性,而不會遍歷原型鏈上的屬性
// 這樣,instance 就有了 defaults、interceptors 屬性。(這兩個屬性後面咱們會介紹)
utils.extend(instance, context);
return instance;
}
// 接收默認配置項做爲參數(後面會介紹配置項),建立一個Axios實例,最終會被做爲對象導出
var axios = createInstance(defaults);
複製代碼
攔截器 interceptors
攔截器分爲請求攔截器(interceptors.request)和響應攔截器(interceptors.response)。
請求攔截器(interceptors.request
)是指能夠攔截住每次或指定http請求,並可修改配置項 ;
響應攔截器(interceptors.response
)是指http請求後攔截,並可修改返回結果項;
數據轉換器
數據轉換器分爲請求轉換器和響應轉換器,顧名思義: 請求轉換器(transformRequest
)是指在請求前對數據進行轉換, 響應轉換器(transformResponse
)主要對請求響應後的響應體作數據轉換。
http請求適配器
config配置項
axios(option)
axios({
url,
method,
headers,
})
複製代碼
axios(url[, option])
axios(url, {
method,
headers,
})
複製代碼
get、delete
等方法):axios[method](url[, option])
axios.get(url, {
headers,
})
複製代碼
post、put
等方法):axios[method](url[, data[, option]])
axios.post(url, data, {
headers,
})
複製代碼
axios.request(option)
axios.request({
url,
method,
headers,
})
複製代碼
http請求適配器、請求地址、請求方法、請求頭header、 請求數據、請求或響應數據的轉換、請求進度、http狀態碼驗證規則、超時、取消請求等。能夠發現,幾乎axios
全部的功能都是經過這個對象進行配置和傳遞的, 既是axios
項目內部的溝通橋樑,也是用戶跟axios
進行溝通的橋樑。
import axios from 'axios'
// 第1種:直接修改Axios實例上defaults屬性,主要用來設置通用配置
axios.defaults[configName] = value;
// 第2種:發起請求時最終會調用Axios.prototype.request方法,而後傳入配置項,主要用來設置「個例」配置
axios({
url,
method,
headers,
})
// 第3種:新建一個Axios實例,傳入配置項,此處設置的是通用配置
let newAxiosInstance = axios.create({
[configName]: value,
})
複製代碼
import axios from 'axios'
axios.defaults.withCredentials = true;
複製代碼
命名三個文件Api.js、ApiURL.js、ApiIp.js,其中ApiIp.js是用來獲取服務器ip地址的,ApiURL.js是用來拼裝ip地址和接口路徑的,固然這個可使用baseURL來實現也能夠,即:axios.defaults.baseURL = 'api.example.com';
Api.js的實現
import axios from 'axios';
import {notification} from 'antd';
import * as ApiURL from 'src/HttpClientRequest/ApiURL';
const key = 'keepOnlyOne';
/** * 數據請求公共方法 * @param apiURL 接口請求路徑 * @param configObj 用戶傳入配置的參數 * @returns {Promise<any>} */
function getDataFromServer(apiURL, configObj) {
// 獲取用戶傳入的接口配置參數
let {
method = 'get',
data = {},
timeout = 3000,
params = {}
} = configObj;
return new Promise(function (resolve, reject) {
axios({
url: apiURL,
method: method,
timeout: timeout,
data: data,
params: params,
headers: {
'Content-Type': 'application/json',
'token': window.sessionStore.getItem('token') || ''
}
}).then((response) => {
if (response) {
if (response.data && response.data.code) {
resolve(response);
} else {
notification.error({
key,
message: '操做失敗',
description: '數據格式有誤'
});
resolve(response);
}
} else {
notification.error({
key,
message: '操做失敗',
description: '服務器錯誤'
});
resolve(response);
}
}).catch((error) => {
notification.error({
key,
message: '操做失敗',
description: '網絡異常,請稍後重試'
});
reject(error);
});
});
}
export function login(configObj) {
return getDataFromServer(ApiURL.LOGIN, configObj);
}
複製代碼
ApiURL.js
import API_IP from './ApiIp';
// 登陸接口地址
export const LOGIN = `${API_IP}/index/login`;
複製代碼
ApiIp.js
// 獲取當前瀏覽器的地址
const interfaceIp = window.location.host;
const imageAddrassIp = window.location.hostname;
// 獲取當前瀏覽器的協議
const browserProtocol = window.location.protocol;
// 進行服務器請求地址的封裝
const serverInterfaceIp = `${browserProtocol}//${interfaceIp}`;
const serverImageIp = `${browserProtocol}//${imageAddrassIp}`;
// 對外提供的請求地址(兼容生產環境和開發環境)
export const API_IP = process.env.NODE_ENV === 'development' ? 'http://121.0.0.1:8080' : serverInterfaceIp;
export const IMAGES_IP = process.env.NODE_ENV === 'development' ? 'http://121.0.0.1' : serverImageIp;
複製代碼