uniapp request请求封装 (携带token,请求拦截)

1.新建utils文件夹,新建uni_request.js,下面的代码复制进去

export default function ({ baseURL, timeout = 56 * 1000, header: headers, statusCode = [200, 401] }) {
	return {
		get(url, data, header, ...args) { return this.request('GET', url, data, { ...header, ...headers }, ...args) },
		post(url, data, header, ...args) { return this.request('POST', url, data, { ...header, ...headers }, ...args) },
		put(url, data, header, ...args) { return this.request('PUT', url, data, { ...header, ...headers }, ...args) },
		delete(url, data, header, ...args) { return this.request('DELETE', url, data, { ...header, ...headers }, ...args) },
		connect(url, data, header, ...args) { return this.request('CONNECT', url, data, { ...header, ...headers }, ...args) },
		head(url, data, header, ...args) { return this.request('HEAD', url, data, { ...header, ...headers }, ...args) },
		options(url, data, header, ...args) { return this.request('OPTIONS', url, data, { ...header, ...headers }, ...args) },
		reace(url, data, header, ...args) { return this.request('TRACE', url, data, { ...header, ...headers }, ...args) },
		uploadFile(url, data, header, ...args) { return this.file('uploadFile', url, data || {}, { ...header, ...headers }, ...args) },
		downloadFile(url, data, header, ...args) { return this.file('downloadFile', url, data || {}, { ...header, ...headers }, ...args) },
		onerror: () => {}, // 请求错误钩子函数集合
		file(method, url, data, header, reqIntercept, resIntercept) {
			let timer, // timer 检测超时定时器
				requestTask, // requestTask 网络请求 task 对象
				aborted = false, // aborted 请求是否已被取消
				overtime = false, // overtime 请求是否超时
				abort = () => { // abort 取消请求方法
					aborted = true // 将请求状态标记为已取消
					requestTask ? requestTask.abort() : '' // 执行取消请求方法
				},
				progressUpdateHandle,
				onProgressUpdate = e => progressUpdateHandle = e // progressUpdateHandle 监听上传进度变化回调,onProgressUpdate 监听上传进度变化方法
			return new Proxy(new Promise((resolve, reject) => { // 返回经过 Proxy 后的 Promise 对象使其可以监听到是否调用 abort 和 onProgressUpdate 方法
				this.interceptors.request.intercept({ header: header || {}, body: data.formData || {} }, method, url, data, reqIntercept).then(async ({ header, body, cancel }) => { // 等待请求拦截器里的方法执行完
					if (aborted || cancel) { // 如果请求已被取消,停止执行,返回 reject
						await this.onerror(method, url, data, '网络请求失败:主动取消')
						return reject('网络请求失败:主动取消')
					}
					requestTask = uni[method]({
						url: url[0] === '/' ? baseURL + url : url,
						name: data.name,
						header,
						filePath: data.filePath,
						formData: body,
					    success: async res => {
							clearTimeout(timer)
							!statusCode.includes(res.statusCode) ? await this.onerror(method, url, data, `网络请求异常:服务器响应异常:状态码:${res.statusCode}`) : '',
							this.interceptors.response.intercept(statusCode.includes(res.statusCode) ? resolve : reject, {
								success: statusCode.includes(res.statusCode), ...res,
							}, method, url, data, reject, resIntercept) // 执行响应拦截器
					    },
						fail: async res => {
							clearTimeout(timer)
							!overtime && await this.onerror(method, url, data, aborted ? '网络请求失败:主动取消' : '网络请求失败:(URL无效|无网络|DNS解析失败)')
							aborted ? reject('网络请求失败:主动取消') : reject('网络请求失败:(URL无效|无网络|DNS解析失败)')
						}
					})
					requestTask.onProgressUpdate(progressUpdateHandle) // 监听下载进度变化
					timer = setTimeout(async () => { // 请求超时执行方法
						overtime = true // 将状态标记为超时,不会被 fail 中的 onerror 重复执行
						requestTask.abort() // 执行取消请求方法
						await this.onerror(method, url, data, '网络请求失败:超时取消')
						reject('网络请求时间超时') // reject 原因
					}, timeout) // 设定检测超时定时器
				})
			}), { get: (target, prop) => {
				if (prop === 'abort') {
					return abort
				} else {
					if (Reflect.get(target, prop) && Reflect.get(target, prop).bind) {
						return Reflect.get(target, prop).bind(target)
					} else {
						return Reflect.get(target, prop)
					}
				}
			} }) // 如果调用 cancel 方法,返回 _watcher.cancel 方法
		},
		request(method, url, data, header, reqIntercept, resIntercept) {
			let timer, // timer 检测超时定时器
				requestTask, // requestTask 网络请求 task 对象
				aborted = false, // aborted 请求是否已被取消
				overtime = false, // overtime 请求是否超时
				abort = () => { // timer 检测超时定时器,requestTask 网络请求 task 对象,aborted 请求是否已被取消,abort 取消请求方法
					aborted = true // 将请求状态标记为已取消
					requestTask ? requestTask.abort() : '' // 执行取消请求方法
				}
			return new Proxy(new Promise((resolve, reject) => { // 返回经过 Proxy 后的 Promise 对象使其可以监听到是否调用 abort 方法
				this.interceptors.request.intercept({ header: header || {}, body: data || {} }, method, url, data, reqIntercept).then(async ({ header, body: data, cancel }) => { // 等待请求拦截器里的方法执行完
					if (aborted || cancel) { // 如果请求已被取消,停止执行,返回 reject
						await this.onerror(method, url, data, '网络请求失败:主动取消')
						return reject('网络请求失败:主动取消')
					}
					requestTask = uni.request({
					    url: url[0] === '/' ? baseURL + url : url,
					    data, method, header,
					    success: async res => { // 网络请求成功
							clearTimeout(timer) // 清除检测超时定时器
							!statusCode.includes(res.statusCode) ? await this.onerror(method, url, data, `网络请求异常:服务器响应异常:状态码:${res.statusCode}`) : '' 
							this.interceptors.response.intercept(statusCode.includes(res.statusCode) ? resolve : reject, {
								success: statusCode.includes(res.statusCode), ...res,
							}, method, url, data, reject, resIntercept) // 执行响应拦截器
					    },
						fail: async res => { // 网络请求失败
							clearTimeout(timer) // 清除检测超时定时器
							!overtime && await this.onerror(method, url, data, aborted ? '网络请求失败:主动取消' : '网络请求失败:(URL无效|无网络|DNS解析失败)')
							aborted ? reject('网络请求失败:主动取消') : reject('网络请求失败:(URL无效|无网络|DNS解析失败)')
						}
					})
					timer = setTimeout(async () => { // 请求超时执行方法
						overtime = true // 将状态标记为超时,不会被 fail 中的 onerror 重复执行
						requestTask.abort() // 执行取消请求方法
						await this.onerror(method, url, data, '网络请求失败:超时取消')
						reject('网络请求时间超时') // reject 原因
					}, timeout  || 12345) // 设定检测超时定时器
				})
			}), { 
				get: (target, prop) => {
					if (prop === 'abort') {
						return abort
					} else {
						if (Reflect.get(target, prop) && Reflect.get(target, prop).bind) {
							return Reflect.get(target, prop).bind(target)
						} else {
							return Reflect.get(target, prop)
						}
					}
				}
			}) // 如果调用 abort 方法,返回 abort 方法
		},
		interceptors: { // 拦截器
			request: {
				interceptors: [],
				use(fun) { this.interceptors.push(fun) },
				async intercept(config, method, url, data, reqIntercept) {
					if (!reqIntercept) { // 如果请求允许被拦截
						for (let i = 0; i < this.interceptors.length; i ++) {
							config = await this.interceptors[i](config, method, url, data)
						}
					}
					return config
				}
			},
			response: {
				interceptors: [],
				use(fun) { this.interceptors.push(fun) },
				async intercept(STATUS, response, method, url, data, reject, resIntercept) {
					try{
						if (!resIntercept) { // 如果请求允许被拦截
							for (let i = 0; i < this.interceptors.length; i ++) {
								response = await this.interceptors[i](response, method, url, data)
							}
						}
						if (response.success) {
							return STATUS(typeof response.data === 'string' ? JSON.parse(response.data) : response.data)
						} else {
							delete response.success
							return STATUS(response, method, url, data)
						}
					}catch(e){
						reject(e)
					}
				}
			}
		}
	}
}

2.新建request文件夹

import uni_request from './uni_request.js'
const request = uni_request({
    baseURL: '',
	header: {'Content-Type': 'application/x-www-form-urlencoded'}
})
request.interceptors.request.use(async (config, ...args) => {
	let token = uni.getStorageSync('token') || 'test token'
	if(!config.header.token) config.header.token = token
	
    return config
})
request.interceptors.response.use((response, ...args) => {
	if(response.data.status == "401"){
		console.log('token无效')
	}
	return response
})
export default request

3.main.js

import request from './utils/request.js'
Vue.prototype.request = request

4.页面使用

this.request.get(' api ') 
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
可以在 `uni-app` 中使用 `axios` 库进行接口请求,并且可以在请求头中添加 `token`。 首先需要安装 `axios` 库: ```bash npm install axios --save ``` 然后在需要使用的地方引入: ```javascript import axios from 'axios' ``` 下面是一个基本的 `axios` 请求封装: ```javascript const request = axios.create({ // 创建 axios 实例 baseURL: 'https://api.example.com', // 设置请求的 base url timeout: 5000, // 设置请求超时时间 }) // 请求拦截request.interceptors.request.use( config => { const token = uni.getStorageSync('token') // 从本地缓存中获取 token if (token) { // 如果 token 存在则在请求头中添加 token config.headers.Authorization = `Bearer ${token}` } return config }, error => { console.log(error) return Promise.reject(error) } ) // 响应拦截request.interceptors.response.use( response => { return response.data }, error => { console.log(error) return Promise.reject(error) } ) export default request ``` 在上面的代码中,我们创建了一个 `axios` 实例,并设置了请求的 `baseURL` 和超时时间。我们还添加了一个请求拦截器,在请求头中添加了 `token`。可以看到,我们使用了 `uni.getStorageSync('token')` 方法从本地缓存中获取了 `token`。在响应拦截器中,我们只返回了响应数据的 `data` 属性。 使用封装好的 `axios` 请求: ```javascript import request from '@/utils/request' request.get('/example').then(response => { console.log(response) }).catch(error => { console.log(error) }) ``` 这样我们就可以在 `uni-app` 中使用 `axios` 库进行接口请求,并且在请求头中添加 `token` 了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值