NextJS中用Server Action从LocalStorage取Token解决跨端请求问题
核心问题:Server Action 无法直接访问 LocalStorage
Server Action 是运行在服务端的代码,而 LocalStorage 是浏览器客户端专属的存储 API,服务端完全没法直接读取它。所以你想直接在 Server Action 里获取 LocalStorage 的 Token 这条路走不通,得换思路解决。
正确实现方案
1. 客户端取 Token,传递给 Server Action
既然 Server Action 在服务端,只能让客户端把 Token 主动传过去:
- 在客户端组件(加
'use client'指令)里读取 LocalStorage 的 Token - 调用 Server Action 时,把 Token 作为参数传入
示例代码:
// 客户端组件 'use client'; import { useState, useEffect } from 'react'; import { serverFetchData } from './actions'; export default function ClientComponent() { const [data, setData] = useState(null); const [loading, setLoading] = useState(false); useEffect(() => { const fetchData = async () => { setLoading(true); try { const token = localStorage.getItem('auth_token'); const res = await serverFetchData(token); setData(res); } catch (err) { console.error('请求失败:', err); } finally { setLoading(false); } }; fetchData(); }, []); if (loading) return <div>加载中...</div>; return <div>{JSON.stringify(data)}</div>; } // Server Action(服务端代码,无需'use client') export async function serverFetchData(token: string | null) { if (!token) throw new Error('未提供Token'); const res = await fetch('https://your-api-endpoint.com/data', { headers: { Authorization: `Bearer ${token}`, }, }); if (!res.ok) throw new Error('接口请求失败'); return res.json(); }
2. 解决重复请求与 Suspense 警告
之前的警告是因为你在客户端组件渲染阶段直接创建了未缓存的 Promise,触发了 Suspense 异常。解决方法:
- 不要在组件渲染时直接调用异步函数,改用
useEffect触发请求 - 如果想用 React 的
use钩子处理异步逻辑,必须配合Suspense组件包裹,同时确保请求有合理缓存(比如用框架自带的 fetch 缓存机制)
use 钩子配合 Suspense 的示例:
'use client'; import { Suspense, use } from 'react'; import { serverFetchData } from './actions'; function DataContent() { const token = localStorage.getItem('auth_token'); const data = use(serverFetchData(token)); return <div>{JSON.stringify(data)}</div>; } export default function ClientWrapper() { return ( <Suspense fallback={<div>加载中...</div>}> <DataContent /> </Suspense> ); }
3. 更优替代:用 Cookie 传递 Token
如果不想每次手动传 Token,可以把 Token 存在 HttpOnly Cookie 里(安全性更高),服务端能直接从请求头的 Cookie 中读取,无需客户端手动传递:
- 登录后,后端把 Token 设置为 HttpOnly Cookie
- Server Action 里直接从请求 Cookie 中获取 Token(以 Next.js 为例)
示例:
// Server Action import { cookies } from 'next/headers'; export async function serverFetchData() { const token = cookies().get('auth_token')?.value; if (!token) throw new Error('未登录'); const res = await fetch('https://your-api-endpoint.com/data', { headers: { Authorization: `Bearer ${token}`, }, }); if (!res.ok) throw new Error('接口请求失败'); return res.json(); }
这种方式既省去了客户端传参的麻烦,HttpOnly Cookie 还能避免 XSS 攻击带来的 Token 泄露风险。
内容的提问来源于stack exchange,提问作者Musiur Alam Opu
相关产品推荐
相关产品推荐

