Skip to content

网络请求

说明

项目使用 Axios 做为异步请求工具,并进行了简单的封装。

接口请求

设置 baseURL

在根目录 .env.* 文件里的 VITE_API_BASEURL 这个参数就是配置 Axios 的 baseURL

例如项目的真实接口请求地址为:

  • https://api.test.com/news/list
  • https://api.test.com/news/create
  • https://api.test.com/shop/info

则可设置为 VITE_API_BASEURL=https://api.test.com

请求调用

ts
import { request } from '@/utils/request'

// GET 请求
request.get('/user', {
  params: {
    page: 1,
    pageSize: 10,
  },
}).then((res) => {
  // 后续业务代码
})

// POST 请求
request.post('/user', {
  username: 'pure-admin',
  password: '123456'
}).then((res) => {
  // 后续业务代码
})

请求拦截器

项目中设置了请求拦截器,主要用于在发送请求前自动处理认证信息:

ts
request.interceptors.request.use((config) => {
  // 获取用户存储中的 token
  const userStore = useUserStore()
  const { accessToken, refreshToken } = storeToRefs(userStore)
  
  // 设置当前语言
  const appStore = useAppStore()
  const { currentLocale } = storeToRefs(appStore)
  config.headers['x-lang'] = currentLocale.value
  
  // 登录接口不需要添加认证头
  if (config.url !== '/user/login') {
    config.headers.authorization = `Bearer ${accessToken.value}`
  }
  
  // 刷新 token 接口使用 refreshToken 作为认证
  if (config.url === '/user/refresh') {
    config.headers.authorization = `Bearer ${refreshToken.value}`
  }
  
  return config
}, error => Promise.reject(error))

响应拦截器

响应拦截器处理统一的响应格式和错误处理:

ts
request.interceptors.response.use(
  (config) => {
    const { data } = config
    
    // 成功响应处理
    if (data.code >= 200 && data.code < 300) {
      // 直接返回数据部分
      return data.data
    } else {
      // 显示错误消息
      message.error(data.message)
      
      return Promise.reject(data)
    }
  },
  // 错误处理在下面的 Token 刷新部分
)

Token 自动刷新机制

项目实现了 Token 自动刷新机制,当访问接口返回 401 未授权错误时,会自动尝试刷新 Token 并重新发起请求。

最佳实践

  • API 封装:将接口调用封装到专门的 API 文件中,而不是直接在组件中使用 request
ts
// apis/user.ts
import { request } from '@/utils/request'

export function getUserList(params) {
  return request.get('/user', { params })
}

export function createUser(data) {
  return request.post('/user', data)
}

// 在组件中使用
import { getUserList } from '@/apis/user'

async function loadUsers() {
  const users = await getUserList({ page: 1 })
  // 处理数据
}
  • 错误处理:在业务代码中正确处理可能的异常
ts
try {
  const result = await createUser(userData)
  message.success('创建用户成功')
  return result
} catch (error) {
  // 拦截器已经显示了错误消息,这里可以做额外处理
  return null
}
  • 并发请求:使用 Promise.all 处理多个并发请求
ts
const [users, roles] = await Promise.all([
  getUserList(),
  getRoleList()
])