一、简介
1.本文主要内容
- 主要记录在uniapp课程项目中使用的通用请求拦截器和响应拦截器代码
- 本文第六部分有以登录注册请求接口的完整代码例子
2.文件目录结构
- api文件夹里分别有api.js和request.js
- api接口代码在api.js里
- 通用拦截器代码在request.js里
二、api接口
@/api/api.js
import api from "./request"
export default {
//获取首页数据 get
getIndexData(){
return api.get('./mobile/index')
}
//登录 post
userLogin(data){
return api.post('./mobile/login',data)
}
}
三、get和post接口
@/api/request.js
import api from "./request"
export default {
config:{...}
get(url, params=null, options={}){
options.url = url
options.url += params ?('?'+Objext.keys(params).map(key => key + '=' + params[key]).join('&') : ''
options.method = 'GET'
return this.request(options)
},
post(url, data = null, options ={}){
options.url = url
options.data = data
options.method = 'POST'
return this.request(options)
}
}
四、request
@/api/request.js
export default {
config:{...}
request(options){
return this.config.beforeRequest(options).then(opt => {
return uni.request(opt)
}).then(this.config.responseRequest)
},
get(){...}
post(){...}
五、通用请求拦截器和响应拦截器
@/api/api.js
import store from "@/store/index.js"
export default {
config:{
//请求拦截器(给请求统一添加 公共请求头、baseUrl、method
beforeRequest(options = {}){
return new Promise((resolve,reject) => {
const baseUrl = 'http://xxxxx.cn'
const appid = 'bd9d01ecc75dbbaaefce'
const token = store.state.token
//添加公共请求参数
options.url = baseUrl + options.url
options.header = {
appid,
token,
}
options.method = options.method || 'GET'
resolve(options)
})
},
//接收参数请求后得到的数据,处理非成功数据reject,并将数据剥离后返回resolve
responseRequest(data) {
return new Promise((resolve,reject) => {
const [error, res] = data
if(res.data.msg != 'ok'){
const msg = res.data.data || '请求失败'
uni.showToast({
title:msg,
icon:'none'
})
if(msg === 'Token 令牌不合法,请重新登录'){
store.dispatch('loginOut')
uni.navigateTo({
url:'/pages/login/login'
})
}
return reject(msg)
}
return resolve(res.data.data)
})
}
},
request (options){...}
get(){...}
post(){...}
}
六、完整代码:以登录注册为例
@/pages/logini/login.vue
//提交表单信息 登录函数
submitLogin(){
if(!this.checked && this.type == 'login'){
return this.$toast('请同意用户协议&隐私声明')
}
const data = Onject.assign(this.form,{})
uni.showLoading({
title:'loading'
})
this.$api['userLogin'](data).then(res => {
this.$toast('登录成功')
this.$store.dispatch('login',res)
})
}
@/api/api.js
import api from "./request"
export default {
//获取首页数据 get
getIndexData(){
return api.get('./mobile/index')
}
//登录 post
userLogin(data){
return api.post('./mobile/login',data)
}
}
@/api/request.js
import store from "@/store/index.js"
export default {
// 请求拦截器 原理:利用微任务.then 让所有使用请求拦截器的函数 在拦截器函数之后执行
config: {
// 请求拦截器(给请求统一添加 公共请求头、baserUrl、method)
beforeRequest(options = {}) {
return new Promise((resolve, reject) => {
const baseUrl = 'http://demonuxtapi.dishait.cn'
const appid = 'bd9d01ecc75dbbaaefce'
const token = store.state.token
// 添加公共请求参数
options.url = baseUrl + options.url
options.header = {
appid,
token
}
options.method = options.method || 'GET'
resolve(options)
})
},
// 响应拦截器 (接收参数请求后得到的数据,处理非成功数据reject,并将数据剥离返回resolve)
responseRequest(data) {
return new Promise((resolve, reject) => {
const [error, res] = data
if (res.data.msg !== 'ok') {
const msg = res.data.data || '请求失败'
uni.showToast({
title: msg,
icon: 'none'
})
if(msg === 'Token 令牌不合法,请重新登录') {
store.dispatch('loginOut')
uni.navigateTo({
url:'/pages/login/login'
})
}
return reject(msg)
}
return resolve(res.data.data)
})
}
},
request(options) {
return this.config.beforeRequest(options).then(opt => {
return uni.request(opt)
}).then(this.config.responseRequest)
},
get(url, params = null, options = {}) {
options.url = url
options.url += params ? ('?' + Object.keys(params).map(key => key + '=' + params[key]).join('&')) : ''
options.method = 'GET'
return this.request(options)
},
post(url, data = null, options = {}) {
options.url = url
options.data = data
options.method = 'POST'
return this.request(options)
},
}