uni-app 前后端分离情况下的请求中间件(构建header和全路径等)

2023-09-05 16:10:04 浏览数 (2)

uni-app

/main.js

代码语言:javascript复制
import Vue from 'vue'
import App from './App'

// 引入封装的request类
import request from './utils/request.js'

Vue.config.productionTip = false
App.mpType = 'app'

// 挂载到全局$http
Vue.prototype.$http = request

const app = new Vue({
    ...App
})
app.$mount()

/utils/request.js

代码语言:javascript复制
import Config from "../config/config.js"
import * as Auth from "./auth.js"

class Request 
{
    /**
     * 构建全路径
     * @param {string} uri
     */
    buildFullUrl(uri) {
        let baseUrl = Config.apiBaseUrl;
        (baseUrl.substring(baseUrl.length-1) !== '/') && (baseUrl  = '/');
        (uri.substring(0, 1) === '/') && (uri = uri.substring(1));
        return baseUrl   uri
    }
    
    /**
     * 构建带authorization的header头
     * @param {Object} headers
     */
    buildHeader(headers) {
        let auth = {'Authorization': 'Bearer '   Auth.getToken()};
        return Object.assign({}, headers || {}, auth);
    }
    
    /**
     * 发送请求 分装成promise
     * @param {string} method
     * @param {string} uri
     * @param {Object} data
     * @param {Object} headers
     */
    request(method, uri, data, headers) {
        return new Promise((resolve, reject) => {
            uni.request({
                url: this.buildFullUrl(uri),
                method: method,
                data: data,
                header: this.buildHeader(headers)
            }).then(result => {
                let [error, res]  = result;
                
                if (error !== null) {
                    uni.showToast({
                        title: '糟糕!好像出了什么问题',
                        icon: 'none',
                        duration: 2000,
                    })
                    // 调试输出
                    reject(error)
                    
                } else {
                    // 认证失败状态,不需要返回,直接跳转登录
                    if (res.statusCode === 401) {
                        uni.showToast({
                            title: '需要登录才能访问',
                            icon: 'none',
                            duration: 2000,
                        });
        
                        setTimeout(() => {
                            uni.redirectTo({
                                url: '/pages/login/login',
                            });
                        }, 2000);
                        // 调试输出
                        reject(res)
                        
                    } else if (res.statusCode >= 200 && res.statusCode <= 299) {
                        // 成功状态
                        resolve(res)
                    } else {
                        // 其他错误状态
                        let errMsg = res.data.message || res.errMsg || '糟糕!好像出了什么问题';
                        uni.showToast({
                            title: errMsg,
                            icon: 'none',
                            duration: 3000,
                        });
                        // 调试输出
                        reject(res)
                    }
                }
            })
            .catch(error => {
                reject(error)
            })
        })
    }
}

export default new Request()

/config/config.js

代码语言:javascript复制
const env = {
    debug: true,
    apiBaseUrl: 'http://api.fmock.com/'
}

export default env

/utils/auth.js

代码语言:javascript复制
/**
 * token存储键名
 */
const TOKENKEY = 'FMOCK-TOKEN-KEY';

/**
 * 前端存储过期时间 (单位天)
 */
const TOKENEXPIRE = 7;

/**
 * 获取token
 */
function getToken() {
    try {
        let res = uni.getStorageSync(TOKENKEY);
        if (res) {
            res = JSON.parse(res);
            if (res.end > new Date().getTime()) {
                return res.key;
            }
        }
    } catch (e) {}
    
    return false;
}

/**
 * 存储token
 * @param {string} token
 */
function setToken(token) {
    try {
        console.log('set token: '   token);
        uni.setStorageSync(TOKENKEY, JSON.stringify({key: token, end: new Date().getTime()   3600000 * 24 * TOKENEXPIRE}))
        return true;
    } catch (e) {
        console.log(e);
        return false;
    }
}

export {getToken, setToken}

使用方式

代码语言:javascript复制
// get
this.$http.request('GET', 'V1/posts?type=all').then(res => {
    console.log("resolve: ", res)
}).catch(e => {
    // 调试输出
    console.log("reject: ", e)
})
    
// post
let data = {"code":"038vtYc313hp4K10j9931V1Sc31vtYcp"};
let header = {"Accept":"application/json"}
this.$http.request('POST', 'V1/oauth/wechat/login', data, header).then((res) => {
    console.log("resolve: ", res)
}).catch(e => {
    // 调试输出
    console.log("reject: ", e)
})

0 人点赞