nuxt框架中的数据持久化最优解+请求拦截器封装

简介: nuxt框架中的数据持久化最优解+请求拦截器封装

前言:


最近掉进了nuxt.js + ts 项目开发这个坑,今日心态炸裂,吐血整理。

1.nuxt项目中的持久化


1.1 Nuxt 有一个 cookie-universal-nuxt 模块来供服务端操作Cookie值 。

npm install cookie-universal-nuxt
使用方法:
提取:data.userInfo = app.$cookies.get('userInfo')
设置:this.$cookies.set("userInfo",this.formData.mobile,{maxAge:60*60*24*3}) //保存3天

1.2 修改根目录下的 nuxt.config.js,在modules中添加

modules: [
'@nuxtjs/axios',
'cookie-universal-nuxt', // ++++
],

1.3.在store目录下的index,js里面有个 nuxtServerInit 方法

// 定义行为
const actions = {
// 服务端调用
nuxtServerInit ({ commit }, { app }) {
const data = {}
data.userInfo = app.$cookies.get(Key.userInfoKey)
data.accessToken = app.$cookies.get(Key.accessTokenKey)
data.refreshToken = app.$cookies.get(Key.refreshTokenKey)
data.redirectURL = app.$cookies.get(Key.redirectURLKey)
commit('UPDATE_ALL_STATE', data)
},
// ....
m

1.4.页面使用

1. 测试,
2. 在 components/layout/Header.vue 中使用
3. this.$store.state.userInfo 可以获取到数据

1.5. 如果报错:Cannot read property 'get' of undefined

解决:查看 mengxuegu-blog-web\nuxt.config.js 文件中后面是否还有 modules: [ ]

image.png

2.请求拦截器的封装


大体分为两步,在plaugins里面建一个.js或者.ts文件,然后在nuxt.config.js中注册,最后重启项目

附上自己封装的拦截器,分为.js版本和ts版本,以供参考:

export default({store, route, redirect, $axios}) => {
    $axios.onRequest(config => {
        alert(config)
        // console.log("请求拦截器")
        const accessToken = store.state.accessToken
        if(accessToken) {
            // Authorization: Bearer token
            config.headers.Authorization = 'Bearer ' + accessToken
        }
        // 请求头添加token
        return config
    })
    $axios.onResponse(response => {
        // console.log('响应拦截器:', response)
        // if(!store.state.accessToken) {
        //     sendRefreshRequest(route, store, redirect)
        // }
        return response
    })
    $axios.onError(error => {
        // console.log('响应异常:', error.response.status)
        if(error.response.status != 401 ) {
            return Promise.reject(error)
        }
        // 401 发送刷新获取新令牌
        sendRefreshRequest(route, store, redirect)
        return  Promise.reject('令牌过期,重新登录')
    })
}
let isLock = true // 防止并发重复发送刷新令牌请求, true 还未发送,false正在请求刷新
const sendRefreshRequest = (route, store, redirect) => {
    if(isLock && store.state.refreshToken) {
        isLock = false
        // 发送请求到认证客户端,通过刷新令牌获取新令牌
        redirect(`${process.env.authURL}/refresh?redirectURL=${redirectURL(route)}`)
    }else {
        isLock = true
        // 没有刷新令牌,跳转到登录页
        // 重置用户状态
        // console.log('跳转到登录页')
        store.commit('RESET_USER_STATE')
        // 跳转到登录页
        redirect(`${process.env.authURL}?redirectURL=${redirectURL(route)}`)
    }
}  
// 获取重定向地址
const redirectURL = (route) => {
    // 客户端
    if(process.client) {
        return window.location.href
    }
    // 服务端 process.env._AXIOS_BASE_URL_  http://localhost:3000/api   http://blog.mengxuegu.com/api
    return process.env._AXIOS_BASE_URL_.replace('api', '') + route.path
}
import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios'
const throwErr = (code: number, response: AxiosResponse) => {
  let message: string = '请求错误'
  switch (code) {
    case 400:
      message = '请求错误'
      break
    case 401:
      message = '未授权,请登录'
      break
    case 403:
      message = '拒绝访问'
      break
    case 404:
      message = `请求地址出错: ${response.config.url}`
      break
    case 408:
      message = '请求超时'
      break
    case 500:
      message = '服务器内部错误'
      break
    case 501:
      message = '服务未实现'
      break
    case 502:
      message = '网关错误'
      break
    case 503:
      message = '服务不可用'
      break
    case 504:
      message = '网关超时'
      break
    case 505:
      message = 'HTTP版本不受支持'
      break
    default:
  }
  return message
}
const requestInterceptors = {
  config: (config: AxiosRequestConfig) => {
    // config.headers = {
    //   'Authorization': 'Bearer'
    // }
    if (config.method && config.params) {
      for (const i in config.params) {
        if (config.params[i] == '' && config.params[i] !== 0 && config.params[i] !== false) {
          config.params[i] = null
        }
      }
    }
    return config
  },
  error: (error: AxiosError) => {
    return Promise.reject(error)
  }
}
const responseInterceptors = {
  response: (response: AxiosResponse) => {
    const res = response.data
    return Promise.resolve(res)
  },
  error: (error: AxiosError) => {
    if (error && error.response) {
      // const res = {
      //   Data: null,
      //   State: error.response.status,
      //   Msg: throwErr(error.response.status, error.response)
      // }
      return Promise.reject(error.response)
    }
  }
}
class Request {
  protected axiosInstance: AxiosInstance;
  constructor(baseURL: string) {
    this.axiosInstance = axios.create({
      baseURL,
      timeout:15000
    })
    this.axiosInstance.interceptors.request.use(requestInterceptors.config, requestInterceptors.error)
    this.axiosInstance.interceptors.response.use(responseInterceptors.response, responseInterceptors.error)
  }
}
export default Request


相关文章
|
2天前
|
前端开发
Axios request 封装技巧:提升代码复用和效率的步骤
在开发中,为了提高效率,通常对 Axios 进行封装,简化了请求的发送和对响应的处理。同时,统一错误处理机制有助于维护代码的清晰和一致性。本文介绍了一些高效封装 Axios 请求的方法。
Axios request 封装技巧:提升代码复用和效率的步骤
|
2天前
第17节:Vue3 反应式代理与原始代理
第17节:Vue3 反应式代理与原始代理
19 0
|
2天前
|
负载均衡 前端开发 Java
字节后端面试题(前端发送请求到后端的过程(MVC),网关gateway作用,怎么解决跨域,各微服务组件作用)
字节后端面试题(前端发送请求到后端的过程(MVC),网关gateway作用,怎么解决跨域,各微服务组件作用)
151 0
|
2天前
|
前端开发
React umi框架局部请求拦截器
React umi框架局部请求拦截器
|
2天前
|
Web App开发 JavaScript 前端开发
深入理解前端跨域方法和原理
深入理解前端跨域方法和原理
|
2天前
|
资源调度 JavaScript API
vue封装axios请求接口并添加前置拦截器和响应拦截器
vue封装axios请求接口并添加前置拦截器和响应拦截器
46 0
|
6月前
|
JavaScript 前端开发 API
vue项目中配置简单的代理与promise,并简单封装请求接口
vue项目中配置简单的代理与promise,并简单封装请求接口
28 0
|
7月前
|
API
76 # koa 上下文的实现原理
76 # koa 上下文的实现原理
19 0
|
9月前
|
前端开发 中间件
[Nestjs] 中间件拦截机制
在NestJS中,中间件拦截机制提供了一种在请求和响应之间对请求进行拦截、修改或中断的方式。中间件拦截器可以用于执行通用的处理逻辑、路由守卫、身份验证、日志记录等操作。
144 0
Yii2的查询构建器是什么?底层原理是什么?
Yii2的查询构建器是什么?底层原理是什么?