这篇文章上次修改于 469 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

app/plugins/api.ts

import { useAuthStore } from '~/stores/auth'

export default defineNuxtPlugin((nuxtApp) => {
  const api = $fetch.create({
    baseURL: '/api/',
    timeout: 10000,
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    // eslint-disable-next-line unused-imports/no-unused-vars
    async onRequest({ request, options, error }) {
      const { token } = useAuthStore()
      if (import.meta.client) {
        options.headers = new Headers(options.headers)
        options.headers.set('Authorization', `Bearer ${token}`)
      }
    },
    // eslint-disable-next-line unused-imports/no-unused-vars
    onResponse({ request, response, options }) {
      // 可在此处理通用响应格式
      const res = response._data as ResultOptions<any>
      if (res.code !== 200) {
        console.warn('API Warning:', res.message || '请求错误')
        ElMessage({ message: `错误码:${res.code}:${res.message || '请求错误'}`, type: 'warning' })
        return Promise.reject(res.message || '请求错误')
      }
    },
    async  onResponseError({ response }) {
      const { clearAuth } = useAuthStore()

      switch (response.status) {
        case 401:
          await clearAuth()
          await nuxtApp.runWithContext(() => navigateTo('/login?expired=1'))
          break

        case 403:
          await nuxtApp.runWithContext(() => navigateTo('/forbidden'))
          break

        case 500:
          showError('服务器内部错误,请稍后重试')
          break

        default:
          console.error('API Error:', response.statusText)
          throw createError({
            statusCode: response.status,
            message: response.statusText,
          })
      }
    },
  })

  return {
    provide: {
      api,
    },
  }
})

nuxt.config.ts

nitro: {
    // 开发代理配置
    devProxy: {
      '/api': {
        target: import.meta.env.NUXT_PUBLIC_API_BASE || 'http://127.0.0.1:5005/api',
        changeOrigin: true,
        prependPath: true,
      },
    },
    // 路由规则
    routeRules: {
      '/api/**': {
        proxy: `${import.meta.env.NUXT_PUBLIC_API_BASE}/**`,
      },
    },
    esbuild: {
      options: {
        target: 'esnext',
      },
    },
    prerender: {
      crawlLinks: false,
      routes: ['/'],
      ignore: ['/hi'],
    },
  },

使用:

import type { AuthFormInput } from './types/auth-input'
import type { AuthResultOutput } from './types/auth-output'

export function useAuthApi() {
  const { $api } = useNuxtApp()

  return {
    // 登录
    login: (input: AuthFormInput) => $api<ResultOptions<AuthResultOutput>>('/sysAuth/login', { method: 'POST', body: input }),
  }
}