uniapp框架配置(拦截器、跨域)及使用

只要创建 uniapp 项目就会有默认配置,但我们都会有解决跨域问题等,所以建好项目配置和封装是必要的。

1.基础配置

根目录新建一个 common 文件夹,里边配置 util.js 、 request.js 、 config.js 可按需配置,以下配上内容

  • util.js
/**
 * 拼接对象为请求字符串
 * 对于需要编码的文本(比如说中文)我们要进行编码
 * @param {Object} obj - 待拼接的对象
 * @returns {string} - 拼接成的请求字符串
 **/
export function formatGetUri(obj, Object) {
	// const params: Array < string >= []
	const params = []
	Object.keys(obj).forEach((key) => {
		let value = obj[key]
		if (typeof value !== 'undefined' || value !== null) {
			params.push([key, encodeURIComponent(value)].json('='))
		}
	})
	return '?' + params.join('&')
}

//表单序列化
export function convertSerialize(data){
    let list = [];
    Object.keys(data).forEach(ele => {
        list.push(`${ele}=${data[ele]}`)
    })
    return list.join('&');
}
  • request.js
import {convertSerialize} from './util.js'
import store from '../store/index.js'
const request = {}
const headers = {}

request.globalRequest = (url, method, data, power) => {
	let header = {}
	/**
	 * 权限判断
	 */
	switch (power) {
		case 0:
			headers['Authorization'] = 'Bearer' + uni.getStorageSync('token')
			// 处理刷新token后重新请求的自定义变量
			headers['refresh_token'] = false
			break
		case 1:
			headers['Authorization'] = 'Basic a3N1ZGk6a3N1ZGk='
			break;
		case 2:
			headers['Authorization'] = 'Basic a3N1ZGlfcGM6a3N1ZGlfcGM='
			break;
		case 3:
			responseType = 'blob'
			break;
		case 4:
			header = {
				'content-type': "application/x-www-form-urlencoded;charset=utf-8"
			}
			break;
		default:
			break;
	}
	//接口公共参数
	const obj = {
		orgId: uni.getStorageSync('orgId') || 0,
		userId: uni.getStorageSync('userId') || 0,
		operator: uni.getStorageSync('loginName') || '匿名',
		timestamp: new Date().getTime()
	}

	let JSONParams = {
		url: url,
		method: method,
		data: { ...obj,
			...data
		},
		dataType: 'JSON',
		header: header,
	}

	if (power != 4) {
		JSONParams = {
			url: url,
			method: method,
			data: { ...obj,
				...data
			},
			dataType: 'JSON',
			header: headers,
		}
	}

	return uni.request(JSONParams).then(res => {
		if (res[1]) {
			//TODO 根据实际后台返回格式修改
			if (res[1].statusCode == 200) {
				// #ifdef H5
				return res[1].data
				// #endif

				// #ifdef MP-WEIXIN
				return JSON.parse(res[1].data)
				// #endif

				// #ifdef APP-PLUS
				return res[1].data
				// #endif
			} else if (res[1].statusCode == 401 && !headers.refresh_token) {
				//接口返回401时认证 续签
				const {url, method, data} = JSONParams
				headers.refresh_token = true
				return store.dispatch('refreshToken').then(res=>{
					uni.setStorageSync('token',res)
					return request.globalRequest(url, method, data, 0)
				})
			} else if (res[1].statusCode == 403) {
				//接口返回403时token过期权限不足,故重登
				uni.redirectTo({
					url: '/pages/public/login'
				})
			} else {
				//抛出异常
				throw res[1].data
			}
		}
	}).catch(params => {
		switch (params.code) {
			case 401:
				uni.clearStorageSync()
				break
			default:
				uni.showToast({
					title: params.message,
					icon: 'none'
				})
				return Promise.reject()
				break
		}
	})
}

export default request

此处用到续签,顺便加上这个功能,不需要时可删除,拦截器拦截401前需在 store 入口文件添加操作,place look

import Vue from 'vue'
import Vuex from 'vuex'
import api from '../api/index.js'
Vue.use(Vuex)

const store = new Vuex.Store({
	state: {},
	actions: {
		async refreshToken(store) {
			let token = uni.getStorageSync('token')
			let refresh_Token = uni.getStorageSync('refreshToken')
			let params = {
				access_token: token,
				refresh_token: refresh_Token,
				grant_type: 'refresh_token',
				client_id: 'flying',
				client_secret: 'yaohw',
			}
			//登录
			let newToken = await api.user.login(params)
			return newToken.value
		}
	}
})

export default store
  • config.js(兼容h5、app、小程序)
let UAC_URL = ""
let DT_WB_URL = ""
//默认路径应与 manifest.json 一致,同时修改
let DEFAULT_UAC_URL = "http://192.168.0.125:9101"
let DEFAULT_DT_WB_URL = "http://192.168.0.125:9102"

if (process.env.NODE_ENV === 'development') {
	// #ifdef H5
	UAC_URL = '/uac'
	DT_WB_URL = '/lift'
	// #endif

	// #ifdef MP-WEIXIN
	UAC_URL = DEFAULT_UAC_URL
	DT_WB_URL = DEFAULT_DT_WB_URL
	// #endif

	// #ifdef APP-PLUS
	UAC_URL = DEFAULT_UAC_URL
	DT_WB_URL = DEFAULT_DT_WB_URL
	// #endif

} else {
	UAC_URL = DEFAULT_UAC_URL
	DT_WB_URL = DEFAULT_DT_WB_URL
}

export default {
	UAC_URL,
	DT_WB_URL
}

2.manifest.json源码试图配置

{
	"h5" : {
		//实现跨域访问
        "devServer" : {
            "port" : 9200, //本机端口
            "disableHostCheck" : true,
            "proxy" : { //访问的ip及端口,可有多个
                "/uac" : {
                    "target" : "http://192.168.0.125:9101/",
                    "changeOrigin" : true,
                    "secure" : false,
                    "pathRewrite" : {
                        "^/uac" : "/"
                    }
                },
                "/lift" : {
                    "target" : "http://192.168.0.125:9102/",
                    "changeOrigin" : true,
                    "secure" : false,
                    "pathRewrite" : {
                        "^/lift" : "/"
                    }
                }
            }
        }
    }
}

3.根目录创建api文件夹

目录安排:
api —— index.js文件、modules文件夹
modules —— js文件(请求接口)

  • index.js 内容
import user from './modules/user.js'
import home from './modules/home.js'
import order from './modules/order.js'
const api = {
	user,
	home,
	order
}
export default api
  • 接口文档,此处用 user.js 举例
import request from '@/common/request.js'
import config from '@/common/config.js'
import {
	formatGetUri
} from '@/common/util.js'

const uac = config.UAC_URL
const lift = config.DT_WB_URL
const user = {}

//轮播图
user.banners = () => request.globalRequest(lift + "/anon/banner/app/valid", 'POST', null, 0)

export default user

4.main.js引入即可使用

import Vue from 'vue'
import App from './App'
import api from 'api/index.js'
import url from './common/config.js'

Vue.config.productionTip = false
Vue.prototype.$fire = new Vue();
Vue.prototype.$api = {
  api
};

Vue.prototype.$url = url;
App.mpType = 'app'

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

5.vue页面请求轮播图接口

//轮播图,接口已在user.js定义
banners() {
	this.$api.api.user.banners().then(res => {
		if (res.result.code == '000000') {
			this.carouselList = res.body
		} else if (res.result.code == '999999') {
			this.$u.toast('丫,网络开小差了')
		} else {
			this.$u.toast(res);
		}
	})
},

到此为止,一个简单的框架就算完成了,还附带了接口请求及调用、token过期重登及续签,希望整理的还算清楚

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值