1. 程式人生 > 實用技巧 >axios的二次封裝和api介面規範

axios的二次封裝和api介面規範

fetch是瀏覽器內建的類,進行資料請求,天生就是基於promise進行管理的

axios是基於ajax和promise進行封裝的庫

下面是axios封裝基本需求

// 二次封裝axios
import axios from 'axios';
import { config } from 'process';
import qs from qs;
// 根據環境變數區分介面的預設地址
switch(process.env.NODE_ENV){
    case "production": //生產環境
        axios.defaults.baseURL = "http://api.yanggengzhen.com";
    
break; case "test": //測試環境 axios.defaults.baseURL = "http://192.168.20.12:8080"; break; default: axios.defaults.baseURL = "http://127.0.0.1:3000" } // 設定超時時間和跨域是否允許攜帶憑證 axios.defaults.timeout = 10000; axios.defaults.withCredentials = true; // 設定POST請求頭,告知伺服器請求主體的資料格式(看伺服器要求什麼格式) // 就算是post請求有些人會要求以xxx=xxx&xxx=xxx的形式傳參,這就是x-www-form-urlencoded格式
axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded'; // 將傳參的json格式的data轉化為xxx=xxx&xxx=xxx axios.defaults.transformRequest = data => { qs.stringify(data)} //設定請求攔截器 // 客戶端傳送請求 ->[請求攔截器] -> 伺服器 // TOKEN校驗(JWT):接收伺服器返回的token,儲存到vuex/本地儲存中,每一次向伺服器發請求,我們應該把token帶上 axios.interceptors.request.use( config =>{ //
config表示請求頭的配置項 // 攜帶上token let token = localStorage.getItem('token'); token && (config.headers.Authorization = token); return config; //不返回config的話後端接收一片空白 },error=>{ return Promise.reject(error); }) // 自己設定哪些狀態碼錶示成功,哪些表示失敗(只要是返回2xx或者3xx都算請求成功,響應攔截器就會走第一個,否則走error) axios.default.validateStatus = function (status){ //狀態碼 return /^(2|3)\d{2}$/.test(status); } // 響應攔截器 // 伺服器返回資訊 -> [攔截的統一請求] ->客戶端js獲取到資訊 axios.interceptors.response.use(response=>{ return response.data; //只拿響應主題內容 },error=>{ let { response } = error; if(response){ // 伺服器有返回結果(常用的錯誤狀態碼) switch (response.status){ case 401: //當前請求需要使用者驗證(一般是未登入)(許可權) break; // 一般操作是跳轉路由或者彈出蒙層 case 403: //伺服器已經理解請求,但是拒絕執行它(一般是token過期) localStorage.removeItem('token') // 跳轉到登陸頁 break; case 404: //找不到頁面或者請求失敗,請求所希望得到的資源未被放在伺服器上發現 break; } return Promise.reject(response) }else{ // 伺服器連結果都沒有返回 if(!window.navigator.onLine){ // 斷網處理:可以跳轉到斷網頁面(把路由導進來,重新連線的時候可以go(-1),路由跳轉,路由資訊儲存) return } return Promise.reject(error) //伺服器返回結果都沒有,並且也沒有斷網,此時應該是服務端的問題 } }) export default axios;

fetch封裝庫基本需求

// fetch
import qs from 'qs'
// 根據環境變數進行介面區分
let baseUrl = '';
let baseURLArr = [
    {
        type:'development',
        url:'http://127.0.0.1:9000'
    },
    {
        type:'test',
        url:'http://192.168.20.15:9000'
    },
    {
        type:'production',
        url:'http://api.yanggengzhen.com'
    }
]
baseURLArr.forEach(item=>{
    if(process.env.NODE_ENV === item.type){
        baseUrl = item.url
    }
})
// 前端請求的時候,傳參的時候轉變為url+? query
// request(url,{
//     params:{

//     }
// })
export default function request(url,options={}){
    url = baseUrl + url; //請求的url ,配置項,如果不傳,預設為空物件
    // get系列請求的處理
    !options.methods?options.methods = 'GET':null;
    if(options.hasOwnProperty('params')){
        if(/^(GET|DELETE|HEAD|OPTIONS)$/i.test(options.methods)){ //判斷是否是get請求
            const ask = url.includes('?')?'&':'?';
            url += `${ask}${qs.stringify(params)}`
        }
        delete options.params;
    }
    // 合併配置項
    options = Object.assign({
        //允許跨域攜帶資源憑證same-origin同源可以 omit都拒絕
        credentials:'include',
        // 設定請求頭
        header:{}
    },options);
    options.headers.Accept = 'application/json';
    // token的校驗
    const token = localStorage.getItem('token');
    token && (options.header.Authorization = token);

    // post請求的處理
    if(/^(POST|PUT)$/i.test(options.methods)){
        !options.type ? options.type = 'urlencoded' :null;
        if(options.type === 'urlencoded'){
            options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
            options.body = qs.stringify(options.body);
        }
        if(options.type === 'json'){
            options.headers['Content-Type'] = 'application/json';
            options.body = JSON.stringify(options.body);
        }
    }
    return fecth(url,options).then(response =>{
        // fecth和axios ajax的區別:不論伺服器返回什麼,都會成功觸發.then
        //返回的結果可能是非200狀態碼
        if(!/^(2|3)\d{2}$/.test(response.status)){
            switch (response.status) {
                case 401: // 當前請求需要使用者驗證(一般是未登入)
                    break;
                case 403: //伺服器已經理解請求,但是拒絕執行它(一般是token過期)
                    break;
                case 404: //請求失敗,請求所希望得到的資源未被再伺服器上發現
                    break;
            }
            return Promise.reject(response)
        }
    }).catch(error => {
        //斷網處理
        if(!window.navigator.onLine){
             //斷開網路了。可以讓其跳轉到斷網頁面
            return;
        }
        return Promise.reject(error)
    })
}

最後製作成統一介面export出去,再到vue原型鏈上掛載屬性,呼叫即可