iT邦幫忙

0

Nuxt localStorage一問

各位大大好
小弟目前正在用NUXT開發網站碰到一個問題
因為目前所接的API都必須帶JWT
所以我把取得JWT Token 寫在 components>nav.vue 裡面
用的方法是打API 取得Token然後寫在localStorage裡面

我的想法是不管我到哪一頁都會先從localStorage取得JWT token然後打需要的api帶入token
然後我每一個頁面都有引入nav.vue這個組件所以每次都會將token重新寫入localStorage
寫完的確也有達到我想要的
但有個bug是如果我的localStorage還沒有token的話就會出現錯誤
原因是我先把畫面渲染出來了 可是渲染之前還沒有token 是渲染後才從nav.vue取得token

渲染頁面 > localStorage取不到token導致打其它API失敗 > 透過nav.vue取得token >頁面渲染完成(但有接API撈資料的地方都空白)

我必須要再重新整理一次(第一次已經透過nav.vue取得token)才能正常使用其它API
不曉得有沒有甚麼方法可以在頁面渲染出來前先取得 token然後寫在localStorage set裡面呢

打JWTAPI > localStorage set token > 渲染頁面 > 透過localStorage取得token打其它API >頁面渲染完成

想要做到這樣應該要怎麼寫比較好呢
還請各位前輩指點一下 謝謝


目前想到的方法是在我每個有打api的地方用setTimeout來執行
不曉得有沒有更好的方法
感覺我的方法不是很正統的

問問題請把程式碼丟出來
不然可能需要找通靈大師
然後請用promise或callback來處理這些需要等待的內容

2 個回答

0
黃彥儒
iT邦高手 1 級 ‧ 2021-11-24 18:34:55
2
通靈亡
iT邦研究生 1 級 ‧ 2021-11-24 23:32:41

你要做的是,把 Token 塞到 Call API 的過程用一個 Plugins js 來設定
而不是把塞 Token 的流程綁在 UI 元件裡面。

使用原生 axios 的 request interceptors 設定

https://axios-http.com/docs/interceptors

nuxt.config.js

export default {
  ...,
  plugins: [
    '~/plugins/axios'
  ],
  ...
}

plugins/axios.js

import axios from 'axios'

export default function (ctx, inject) {
  axios.interceptors.request.use(
   config => {
       const token = localStorage.getItem('token')
       if (token) {
           config.headers['Authorization'] = `Bearer ${token}`
       }
       return config;
   },
   error => {
       Promise.reject(error)
   });

  inject('axios', axios)
}

使用 nuxt/axios 的 onRequest interceptors 設定

https://axios.nuxtjs.org/extend

nuxt.config.js

export default {
  modules: ['@nuxtjs/axios'],
  ...,
  plugins: [
    '~/plugins/axios'
  ],
  ...
}

plugins/axios.js

export default function ({ $axios, store }) {
 $axios.onRequest(() => {
     const token = localStorage.getItem('token')
     if (token) {
         config.headers.common['Authorization'] = `Bearer ${token}`
     }
 })
}

呼叫 $axios

export default {
  async asyncData({ $axios }) {
    const test = await $axios.$get('http://test.com')
    return { test }
  },
  
  mounted() {
    this.test = await this.$axios.$get('http://test.com')
  }
}

我要發表回答

立即登入回答