以前一直用 vue3
,现在在学习用 nuxt3
,遇到一个传 token
的问题,研究半天没明白,nuxt3
这个 token
要怎么请求的时候传过去?
我先讲下我的 vue3
是怎么用的
用户第一次访问网站,检查 localStorage.getItem('token')
是否为空,如果为空或token
过时,直接跳到登录页面,登录后获取 token
存放到 localStorage.setItem('token', token)
里面,之后每次页面的所有请求都在 headers.Authorization
里面带上,如下:
import axios from 'axios';
axios.post('/api/users', {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
}
}).then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
那 nuxt3
获取的 token
放在哪,怎么在下面请求中带上?
const { data } = await useFetch('/api/users');
xxx.vue
文件中,更本就不能使用 localStorage
,该怎么做?
网上都说用用 useState
,
// states.ts
export const useToken = () => useState<string>('token', () => '');
登录后获取 token
,存到 useToken().value = token
里面,那我刷新页面不就没了
这里主要涉及一个思路的转换。
在 Vue,或者说传统 SPA 里,所有请求都是 后 请求,即完成网页加载、JS 执行完毕后,再发起请求。这些请求,可以认为完全由开发者控制,即你知道什么时候该请求,然后发起请求。一般来说,所有的请求都是 数据交互类。
在 Nuxt 里,因为 SSR 的存在,所以请求至少可以分成两类:页面渲染类,数据交互类。前者会影响到 HTML 的内容。在网络环境里,存在大量缓存节点,假如跟用户相关的敏感数据渲染成 HTML,缓存到 CDN 当中,会是非常大的安全问题。所以 Nuxt 在 SSR 及其内部发起请求时,不会携带 cookie;在用户主动发起的请求里,才会携带 cookie。
回到你的问题。
localStorage
存在用户本地,无法在网络请求中携带,所以必须在网页准备就绪后才能使用localStorage
的请求就不能放在useAsyncData
、useFetch
里,因为它们都是 SSR 的关键函数,它们第一次起作用的时候,运行环境是线上的 node.jsserver: false
,或者在onMounted()
里使用$fetch
请求,用传统 SPA 的形式就可以了。