Remix中重定向页面时如何传递数据?
问题分析
Remix 中 redirect 函数的 data 参数不会随重定向传递到目标页面——因为重定向会触发浏览器发起全新的 GET 请求,原请求的 data 无法被携带到新页面的 loader 中,这就是你当前代码无法获取数据的核心原因。
可行解决方案
以下是两种常用的实现方式,根据数据敏感度选择:
方案一:URL 查询参数(适合非敏感数据)
将需要传递的数据编码后拼接到重定向 URL 中,在目标页面的 loader 里读取查询参数。
登录页(Component 1)修改后的 loader:
export const loader = async ({ request }: LoaderArgs) => { const session = await getSession(request); if (condition === true) { // 对特殊字符编码,避免 URL 解析异常 const reason = encodeURIComponent('we logged you out because of xyz'); return redirect(`/bye?reason=${reason}`, { headers: { "Set-Cookie": await sessionStorage.destroySession(session), }, }); } return json({}); };
/bye 页面代码:
// 新增 loader 读取查询参数 export const loader = async ({ request }: LoaderArgs) => { const url = new URL(request.url); const reason = url.searchParams.get('reason'); return json({ reason: decodeURIComponent(reason || '') }); }; export default function Bye() { const { reason } = useLoaderData<typeof loader>(); return ( <div> <h1>Off you go</h1> <p>Some Data: {reason}</p> </div> ); }
方案二:临时 Cookie(适合敏感数据,不暴露在 URL 中)
在重定向时设置一个短期有效的临时 Cookie,目标页面读取后立即清除它。
登录页(Component 1)修改后的 loader:
export const loader = async ({ request }: LoaderArgs) => { const session = await getSession(request); if (condition === true) { // 设置有效期1分钟的临时Cookie,足够完成跳转读取 const tempCookie = `logout_reason=${encodeURIComponent('we logged you out because of xyz')}; Path=/; Max-Age=60`; return redirect("/bye", { headers: { "Set-Cookie": [ await sessionStorage.destroySession(session), tempCookie ], }, }); } return json({}); };
/bye 页面代码:
// 新增 loader 读取并清除临时Cookie export const loader = async ({ request }: LoaderArgs) => { const cookies = request.headers.get('Cookie'); let reason = ''; let clearCookie = ''; if (cookies) { const cookieMap = Object.fromEntries( cookies.split(';').map(cookie => { const [key, value] = cookie.trim().split('='); return [key, decodeURIComponent(value)]; }) ); reason = cookieMap.logout_reason || ''; // 读取后立即清除临时Cookie clearCookie = 'logout_reason=; Path=/; Max-Age=0'; } return json({ reason }, { headers: clearCookie ? { "Set-Cookie": clearCookie } : {} }); }; export default function Bye() { const { reason } = useLoaderData<typeof loader>(); return ( <div> <h1>Off you go</h1> <p>Some Data: {reason}</p> </div> ); }
内容的提问来源于stack exchange,提问作者IsaacK
相关产品推荐
相关产品推荐

