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原型鏈上掛載屬性,調用即可

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM