laravel封装请求带状态加载token
完整代码:utils/request.js
// utils/request.js
// 基础配置
const BASE_URL = 'https://your-api.com/api' // 替换为你的接口地址
// 请求封装类
class HttpRequest {
constructor() {
this.config = {
baseUrl: BASE_URL,
header: {
'Content-Type': 'application/json'
}
}
this.queue = {} // 请求队列(用于防止重复提交)
}
// 核心请求方法
async request(options) {
// 合并配置
const mergedOptions = {
...this.config,
...options,
url: this.config.baseUrl + options.url
}
// 显示加载状态(可配置)
if (mergedOptions.showLoading !== false) {
uni.showLoading({
title: '加载中...',
mask: true
})
}
// 防止重复提交
const requestKey = `${mergedOptions.url}_${JSON.stringify(mergedOptions.data)}`
if (this.queue[requestKey]) {
return Promise.reject(new Error('重复请求已被拦截'))
}
this.queue[requestKey] = true
// 添加 Token
const token = uni.getStorageSync('token')
if (token) {
mergedOptions.header = {
...mergedOptions.header,
Authorization: `Bearer ${token}`
}
}
return new Promise((resolve, reject) => {
uni.request({
...mergedOptions,
success: (res) => {
// 隐藏加载状态
if (mergedOptions.showLoading !== false) {
uni.hideLoading()
}
// 移除请求队列标记
delete this.queue[requestKey]
// 处理 HTTP 状态码
if (res.statusCode !== 200) {
return this.handleHttpError(res.statusCode, res.data)
}
// 处理业务逻辑(假设接口返回格式为 { code: 200, data: {}, message: 'success' })
if (res.data.code !== 200) {
return this.handleBusinessError(res.data.code, res.data.message)
}
// 返回数据
resolve(res.data.data)
},
fail: (err) => {
// 隐藏加载状态
if (mergedOptions.showLoading !== false) {
uni.hideLoading()
}
// 移除请求队列标记
delete this.queue[requestKey]
// 处理网络错误
reject(new Error('网络请求失败'))
uni.showToast({
title: '网络请求失败',
icon: 'none'
})
}
})
})
}
// 处理 HTTP 错误
handleHttpError(statusCode, data) {
const errorMap = {
400: '请求参数错误',
401: () => {
uni.removeStorageSync('token')
uni.reLaunch({ url: '/pages/login/login' })
return '登录已过期,请重新登录'
},
403: '没有操作权限',
404: '资源不存在',
500: '服务器错误',
502: '网关错误'
}
const errorHandler = errorMap[statusCode] || (() => `网络请求错误 (${statusCode})`)
const errorMessage = typeof errorHandler === 'function' ? errorHandler() : errorHandler
uni.showToast({
title: errorMessage,
icon: 'none'
})
return Promise.reject(new Error(errorMessage))
}
// 处理业务错误
handleBusinessError(code, message) {
const errorMessages = {
1001: '参数校验失败',
1002: '操作过于频繁',
// ...其他业务错误码
}
const errorMessage = errorMessages[code] || message || '操作失败'
uni.showToast({
title: errorMessage,
icon: 'none'
})
return Promise.reject(new Error(errorMessage))
}
// 快捷方法
get(url, params, options) {
return this.request({
method: 'GET',
url,
data: params,
...options
})
}
post(url, data, options) {
return this.request({
method: 'POST',
url,
data,
...options
})
}
put(url, data, options) {
return this.request({
method: 'PUT',
url,
data,
...options
})
}
delete(url, data, options) {
return this.request({
method: 'DELETE',
url,
data,
...options
})
}
}
// 创建实例
const http = new HttpRequest()
// 导出实例
export default http
使用示例
- 在 Vue 组件中使用
<template> <view> <button @click="fetchData">获取数据</button> </view> </template>
<script>
import http from '@/utils/request'
export default {
methods: {
async fetchData() {
try {
const data = await http.get('/user/info', { id: 1 })
console.log('获取数据成功:', data)
} catch (err) {
console.error('请求失败:', err)
}
}
}
}
</script>
2. 在页面中使用
import http from '@/utils/request'
export default {
onLoad() {
this.loadData()
},
methods: {
async loadData() {
try {
const result = await http.post('/submit', { name: 'test' })
console.log('提交成功:', result)
} catch (err) {
console.error('提交失败:', err)
}
}
}
}
主要功能说明 自动携带 Token:
从本地存储中读取 token,并自动添加到请求头中。
如果 Token 过期(401 状态码),会自动跳转到登录页。
状态拦截:
统一处理 HTTP 状态码(如 400、401、403、500 等)。
支持自定义业务错误码处理。
防止重复提交:
相同的请求在未完成前会被拦截,避免重复提交。
加载状态:
默认显示全局 Loading,支持单个请求禁用 Loading。
错误提示:
网络错误、HTTP 错误、业务错误都会通过 uni.showToast 提示用户。 配置说明 修改基础地址:
将 BASE_URL 替换为你的接口地址。
Token 存储:
登录成功后,调用以下代码存储 Token:
uni.setStorageSync('token', 'your_token_here')
禁用 Loading:
如果某个请求不需要显示 Loading,可以传入 showLoading: false:
http.get('/user/info', { id: 1 }, { showLoading: false })
最近访问时间:2025-05-01 02:12:48