動態Axios配置

推薦使用Vue-cli工具來建立和管理項目,就算剛開始不熟悉,用着用着即可知曉其中的奧妙。前一段時間官方所推薦的數據請求插件仍是 Vue-resource,但如今已經變了,變成了 Axios,不用知道爲何變了,反正這個用起來比那個好一些,用就是了,下面是一些封裝 axios請求的一些經驗,不對之處,還望多多指教!

01

建立文件,Vue項目初始化以後,在src目錄下再建立一個util工具文件夾,通常就是用來存放一些封裝的函數方法,如今讓咱們在util文件目錄下建立一個http.js文件,封裝axios方法。css

02

直接上代碼(常規版),代碼中有詳細的註釋vue

import axios from 'axios' //引用axios
import {Promise} from 'es6-promise'   //引入Promise

// axios 配置
axios.defaults.timeout = 5000;  //設置超時時間
axios.defaults.baseURL = 'http://localhost:4000/api/v1/'; //這是調用數據接口

// http request 攔截器(全部發送的請求都要從這兒過一次),經過這個,咱們就能夠把token傳到後臺,我這裏是使用sessionStorage來存儲token等權限信息和用戶信息,若要使用cookie能夠本身封裝一個函數並import即可使用
axios.interceptors.request.use(
    config => {
        const token = sessionStorage.getItem("token"); //獲取存儲在本地的token
        config.data = JSON.stringify(config.data);
        config.headers = {
            'Content-Type':'application/json' //設置跨域頭部,雖然不少瀏覽器默認都是使用json傳數據,但咱要考慮IE瀏覽器。
        };
        if (token) {
            config.headers.Authorization = "Token " + token; //攜帶權限參數
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    }
);


// http response 攔截器(全部接收到的請求都要從這兒過一次)
axios.interceptors.response.use(
    response => {
//response.status===401是我和後臺約定的權限丟失或者權限不夠返回的狀態碼,這個能夠本身和後臺約定,約定返回某個自定義字段也是能夠的
        if(response.status == 401) {
            router.push({ //push後面是一個參數對象,能夠攜帶不少參數,具體能夠去vue-router上查看,例如query字段表示攜帶的參數
                path: '/login' 
            })
        }
        return response;
    },
    error => {
        return Promise.reject(error.response.data)
    });

export default axios;

/**
 * fetch 請求方法
 * @param url
 * @param params
 * @returns {Promise}
 */
export function fetch(url, params = {}) {

    return new Promise((resolve, reject) => {
        axios.get(url, {
            params: params
        })
        .then(response => {
            resolve(response.data);
        })
        .catch(err => {
            reject(err)
        })
    })
}

/**
 * post 請求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
export function post(url, data = {}) {
    return new Promise((resolve, reject) => {
        axios.post(url, data)
            .then(response => {
                resolve(response.data);
            }, err => {
                reject(err);
            })
    })
}

/**
 * patch 方法封裝
 * @param url
 * @param data
 * @returns {Promise}
 */
export function patch(url, data = {}) {
    return new Promise((resolve, reject) => {
        axios.patch(url, data)
            .then(response => {
                resolve(response.data);
            }, err => {
                reject(err);
            })
    })
}

/**
 * put 方法封裝
 * @param url
 * @param data
 * @returns {Promise}
 */
export function put(url, data = {}) {
    return new Promise((resolve, reject) => {
        axios.put(url, data)
            .then(response => {
                resolve(response.data);
            }, err => {
                reject(err);
            })
    })
}

03

(動態版)axios的攔截器不是必要的,不是每一個項目都須要,並且headers裏面的Content-TypeAuthorization不止一種,這時就須要使用另外一種方法。ios

util/http.js
import axios from 'axios' //引用axios
import {Promise} from 'es6-promise'   //引入Promise

// axios 配置和攔截器都不用了,這裏我使用了一個動態配置數據請求地址,在App.vue中,代碼在下面,這個也不是必須的。


//^_^下面都設置一個默認的頭部,使用的時候能夠傳入數據覆蓋^_^,例如使用fetch(GET)方法時,沒有請求數據,可是請求頭有變化,則應寫成 fetch("地址", {}, {"這裏寫頭部的內容"})   記住沒數據用一個空對象佔位置
/**
 * fetch 請求方法
 * @param url
 * @param params
 * @returns {Promise}
 */
export function fetch(url, params = {}, headers = {
    'Content-Type': 'application/json', //設置跨域頭部
    "Authorization": 'JWT ' + sessionStorage.getItem("authToken")
}) {

    return new Promise((resolve, reject) => {
        axios.get(url, {
            params: params,
            headers: headers
        })
        .then(response => {
            resolve(response.data);
        })
        .catch(err => {
            reject(err.response)
        })
    })
}

/**
 * post 請求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
export function post(url, data = {}, config = {
    "headers": {
        'Content-Type': 'application/json', //設置跨域頭部
        "Authorization": 'JWT ' + sessionStorage.getItem("authToken")
    }
}) {
    return new Promise((resolve, reject) => {
        axios.post(url, data, config)
            .then(response => {
                resolve(response.data);
            }, err => {
                reject(err.response);
            })
    })
}

/**
 * patch 方法封裝
 * @param url
 * @param data
 * @returns {Promise}
 */
export function patch(url, data = {}, config = {
    "headers": {
        'Content-Type': 'application/json', //設置跨域頭部
        "Authorization": 'JWT ' + sessionStorage.getItem("authToken")
    }
}) {
    return new Promise((resolve, reject) => {
        axios.patch(url, data, config)
            .then(response => {
                resolve(response.data);
            }, err => {
                reject(err.response);
            })
    })
}

/**
 * put 方法封裝
 * @param url
 * @param data
 * @returns {Promise}
 */
export function put(url, data = {}, config = {
    "headers": {
        'Content-Type': 'application/json', //設置跨域頭部
        "Authorization": 'JWT ' + sessionStorage.getItem("authToken")
    }
}) {
    return new Promise((resolve, reject) => {
        axios.put(url, data, config)
            .then(response => {
                resolve(response.data);
            }, err => {
                reject(err.response);
            })
    })
}
App.vue(這是在 src目錄下的程序入口文件)
<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
import axios from 'axios';
let protocol = window.location.protocol; //協議
let host = window.location.host; //主機
let reg = /^localhost+/;
if(reg.test(host)) {
  //若本地項目調試使用
  axios.defaults.baseURL = 'http://10.0.xx.xxx:xxxx/api/';
} else {
  //動態請求地址
  axios.defaults.baseURL = protocol + "//" + host + "/api/";
}
axios.defaults.timeout = 30000;
export default {
  name: 'app',
  axios   //這裏記得導出,若請求地址永久固定一個,則就按照`普通版`配置一個baserURL就能夠了
}
</script>

<style lang="scss">  //這裏我使用的是scss
@import '~@/style/style'
</style>

04

總結es6

  • 常見問題vue-router

    • 在使用動態版時,爲何稱爲動態呢,是由於訪問地址和請求地址是同一個地址可端口號,例如我經過http://www.cmgos.com(默認端口80)訪問項目,那麼個人baseURL會自動的變爲http:www.cmgos.com:80/api/,這麼作的緣由是當某一天項目遷移或者http改成https時,不用你再去更改請求地址,程序自動就完成了
    • 數據請求地址配置不正確?若是你配置了baseURL,那麼你封裝的函數在使用時僅需傳入基於baseURL的請求地址,例如傳入login/那麼請求地址會自動變爲http:www.cmgos.com:80/api/login/,若未配置,那麼能夠直接傳入整個請求地址
  • 注意事項json

    • 在使用動態版時,因爲沒有使用攔截器,因此下面封裝的函數在返回錯誤的時候須要寫成err.response.data來獲取返回的數據,但我寫的是err.response,由於這樣能夠拿到(status)狀態碼等信息,若不須要判斷返回的狀態碼,則改成err.response.data即可
相關文章
相關標籤/搜索