1. 程式人生 > >Vue Axios 的封裝使用

Vue Axios 的封裝使用

[toc] ------ ## Axios 說明 Axios 是一個基於 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。 --- ## 安裝 `npm` 中安裝 ```node npm install axios ``` 使用 `cdn`: ```node ``` ## Axios 請求配置 下面的都是針對請求時可以設定的配置項,只有 `url` 是必須的,若沒有指定,則預設使用 `get` 方式請求。 ```js { // `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: { userId: 1 }, // `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: { userName: 'levy' }, // `timeout` 指定請求超時的毫秒數(0 表示無超時時間) // 如果請求話費了超過 `timeout` 的時間,請求將被中斷 timeout: 1000, // `withCredentials` 表示跨域請求時是否需要使用憑證 withCredentials: false, // 預設的 // `adapter` 允許自定義處理請求,以使測試更輕鬆 // 返回一個 promise 並應用一個有效的響應 (查閱 [response docs](#response-api)). adapter: function (config) { /* ... */ }, // `auth` 表示應該使用 HTTP 基礎驗證,並提供憑據 // 這將設定一個 `Authorization` 頭,覆寫掉現有的任意使用 `headers` 設定的自定義 `Authorization`頭 auth: { username: 'levy', password: '123456' }, // `responseType` 表示伺服器響應的資料型別,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' responseType: 'json', // 預設的 // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名稱 xsrfCookieName: 'XSRF-TOKEN', // default // `xsrfHeaderName` 是承載 xsrf token 的值的 HTTP 頭的名稱 xsrfHeaderName: 'X-XSRF-TOKEN', // 預設的 // `onUploadProgress` 允許為上傳處理進度事件 onUploadProgress: function (progressEvent) { // 對原生進度事件的處理 }, // `onDownloadProgress` 允許為下載處理進度事件 onDownloadProgress: function (progressEvent) { // 對原生進度事件的處理 }, // `maxContentLength` 定義允許的響應內容的最大尺寸 maxContentLength: 2500, // `validateStatus` 定義對於給定的HTTP 響應狀態碼是 resolve 或 reject promise 。 //如果 `validateStatus` 返回 `true` (或者設定為 `null` 或 `undefined`),promise 將被 resolve; 否則,promise 將被 rejecte validateStatus: function (status) { return status >= 200 && status < 300; // 預設的 }, // `maxRedirects` 定義在 node.js 中 follow 的最大重定向數目 // 如果設定為0,將不會 follow 任何重定向 maxRedirects: 5, // 預設的 // `httpAgent` 和 `httpsAgent` 分別在 node.js 中用於定義在執行 http 和 https 時使用的自定義代理。允許像這樣配置選項: // `keepAlive` 預設沒有啟用 httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), // 'proxy' 定義代理伺服器的主機名稱和埠 // `auth` 表示 HTTP 基礎驗證應當用於連線代理,並提供憑據 // 這將會設定一個 `Proxy-Authorization` 頭,覆寫掉已有的通過使用 `header` 設定的自定義 `Proxy-Authorization` 頭。 proxy: { host: '127.0.0.1', port: 8080, auth: : { username: 'levy', password: '123456' } }, // `cancelToken` 指定用於取消請求的 cancel token // (檢視後面的 Cancellation 這節瞭解更多) cancelToken: new CancelToken(function (cancel) { }) } ``` ## 響應結構 通常的請求響應結構體如下: ```js { // `data` 由伺服器提供的響應 data: {}, // `status` 來自伺服器響應的 HTTP 狀態碼 status: 200, // `statusText` 來自伺服器響應的 HTTP 狀態資訊 statusText: 'OK', // `headers` 伺服器響應的頭 headers: {}, // `config` 是為請求提供的配置資訊 config: {} } ``` ## 常用請求方法 在使用 axios 時,只要在當前操作窗體中 引用了 axios 後,都可以使用如下方法, 或者全域性引入了 axios。 ```js axios.request(config) axios.get(url[, config]) axios.delete(url[, config]) axios.head(url[, config]) axios.post(url[, data[, config]]) axios.put(url[, data[, config]]) axios.patch(url[, data[, config]]) ``` ## 預設值配置 在程式請求中,肯定都有多個請求,而某些配置都是預設固定且相同的 ### 全域性的 請求配置項 因此可以設定全域性的 請求配置項 預設值 例如 ```js axios.defaults.baseURL = 'https://api.example.com' axios.defaults.headers.common['token'] = AUTH_TOKEN axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8' ``` ### 自定義例項預設值 ```js // 建立例項時設定配置的預設值 var instance = axios.create({ baseURL: 'https://api.example.com', }) // 在例項已建立後修改預設值 instance.defaults.headers.common['token'] = AUTH_TOKEN ``` ### 配置的優先順序 配置會以一個優先順序進行合併。這個順序是:在 `lib/defaults.js` 找到的庫的預設值,然後是例項的 `defaults` 屬性,最後是請求的 `config` 引數。**後者將優先於前者**。 這裡只是以超時時間(其它配置項一樣的設定方式)寫的一個例子: ```js // 使用由庫提供的配置的預設值來建立例項 // 此時超時配置的預設值是 `0` var instance = axios.create() // 全域性配置時 覆寫庫的超時預設值 // 現在,在超時前,所有請求都會等待 2.5 秒 instance.defaults.timeout = 2500 // 在單個請求時 為已知需要花費很長時間的請求覆寫超時設定 instance.get('/longRequest', { timeout: 5000, }) ``` ## 攔截器 在請求或響應被 then 或 catch 處理前攔截它們。 ```js // 新增請求攔截器 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) } ) ``` 如果你想在稍後移除攔截器,可以這樣: ```js var myInterceptor = axios.interceptors.request.use(function () { /*...*/ }) axios.interceptors.request.eject(myInterceptor) ``` 可以為自定義 axios 例項新增攔截器 ```js var instance = axios.create() instance.interceptors.request.use(function () { /*...*/ }) ``` ## 個人完整 `axios` 配置 新建一個資料夾 專門管理 axios 的全域性預設配置 config.js 項如下: 下面的 `baseUrl` 可在 `.env.production` 和 `.env.development` 加對應引數,然後使用 `process.env.baseUrl` **需要特別注意的是 `.env.production`和`.env.development`檔案 引數說明:** - NODE_ENV - 是 “development”、“production” 、"test"或者自定義的值。具體的值取決於應用執行的模式 - BASE_URL - 會和 vue.config.js 中的 publicPath 選項相符,即你的應用會部署到的基礎路徑 - 除了 NODE*ENV 和 BASE_URL,其他的環境變數必須以 VUE_APP* 開頭 - 專案中使用:process.env.環境變數名,eg:VUE_APP_BASE_URL ```js const urlMap = { development: 'http://localhost:5000/', production: '', //線上環境IP地址 } const baseUrl = urlMap[process.env.NODE_ENV] export default { method: 'get', // 基礎url字首 baseURL: baseUrl, // 請求頭資訊 headers: { 'Content-Type': 'application/json;charset=UTF-8', }, // 引數 data: {}, // 設定超時時間 timeout: 10000, // 返回資料型別 responseType: 'json', } ``` 然後 新建 axios 的配置檔案,`axiosHttp.js`。 ```js import axios from 'axios' import qs from 'qs' import router from '@/router' import config from './config' axios.defaults.timeout = config.timeout axios.defaults.headers = config.headers axios.defaults.baseURL = config.baseURL // 請求攔截器 axios.interceptors.request.use( (config) => { // 觸發loading效果 //判斷是否存在token,如果存在,則在header上加上token // let token = getStore('token') // if (token) { // config.headers.common['token'] = token // } // if (config.method == 'post' || config.method == 'put') { // //將資料轉成string // config.data = JSON.stringify(config.data) // } else if (config.method == 'get') { // //&& browser.isIE // //給Get新增時間戳 解決IE快取問題 // let symbol = config.url.indexOf('?') >= 0 ? '&' : '?' // config.url += symbol + '_=' + Date.now() // config.data = qs.stringify(config.data) // } return config }, (err) => { // 關閉loading // 失敗提示 return Promise.resolve(err) } ) // 響應攔截器 axios.interceptors.response.use( (response) => { // 關閉loading if (!response || !response.data || !response.data.success) { // 失敗提示 } else if (response.data.data && response.data.code == 200) { // 成功處理 } if (response.data) { switch (response.data.code) { case 401: // 返回 401 清除token資訊並跳轉到登入頁面 // store.commit('LOGOUT') setTimeout(function () { router.replace({ path: '/login', // 登入成功後跳入瀏覽的當前頁面 // query: {redirect: router.currentRoute.fullPath} }) }, 1500) break case 402: //402無許可權操作 // 提示 return new Promise(() => {}) //外部不會再處理 break } } return response }, (err) => { // 關閉loading // 提示異常 // return Promise.resolve(err); //外部不會再處理 return new Promise(() => {}) } ) export default { Get(url, params = {}) { return new Promise((resolve, reject) => { axios .get(url, { params }) .then((res) => { resolve(res.data) }) .catch((error) => { reject(error) //resolve(error) }) }) }, Post(url, params = {}) { return new Promise((resolve, reject) => { axios .post(url, params) .then((res) => { resolve(res.data) }) .catch((error) => { reject(error) //resolve(error) }) }) }, Delete(url, params = {}) { return new Promise((resolve, reject) => { axios .delete(url, params) .then((res) => { resolve(res.data) }) .catch((error) => { reject(error) //resolve(error) }) }) }, Put(url, params = {}) { return new Promise((resolve, reject) => { axios .put(url, params) .then((res) => { resolve(res.data) }) .catch((error) => { reject(error) //resolve(error) }) }) }, } ``` 在各個模組引入 axiosHttp.js 檔案,直接使用裡面的方法,首字元大寫。 在 api 檔案中將各個模組引入,在 main.js 中將 api 全域性掛載到 vue 的屬性上。在頁面上的呼叫則為 `this.$api.methodName` 原文地址:[http://book.levy.net.cn/doc/frontend/axios.html](http://book.levy.net.cn/doc/frontend/axio