Remix - 无法“设置 Cookie”除了当前路由的加载器的响应之外的任何地方
我有世界上最基本的混音应用程序设置来尝试找出 createStorageSessionCookies ,它们似乎只能在调用 API 的 UI 路由的加载器中设置。
示例:
- 索引UI路由
- API在routes/api/testApi.tsx(这是一个只有一个操作的资源路由)
- app/session.server.ts,我使用createStorageSessionCookies()创建存储会话cookie
如果我尝试设置cookie除了 Index UI 路由中的加载程序返回之外的其他任何地方,它都不起作用。如果我调用 testApi 并尝试返回设置 cookie 的响应,则不起作用。如果我创建一个从加载程序调用的单独函数,并且该函数返回 API 调用的结果并尝试设置 cookie,则不起作用。实际上,只有当我在加载程序的响应中设置 cookie 时,它才有效。
示例索引路由在哪里工作
export const loader: LoaderFunction = async ({ request }) => {
const session = await sessionStorage.getSession(
request.headers.get('Cookie')
);
session.set('cookie_example', 'thisworks');
return json(
{ status: 'this works' },
{
headers: {
'Set-Cookie': await sessionStorage.commitSession(session),
},
}
);
};
export default function Index() {
const data = useLoaderData();
return <div>hi</div>;
}
这不会工作
const setCookie = async (request: Request) => {
const session = await sessionStorage.getSession(
request.headers.get('Cookie')
);
session.set('cookie_example', 'thisdoesntwork');
return json(
{ status: 'this doesnt work' },
{
headers: {
'Set-Cookie': await sessionStorage.commitSession(session),
},
}
);
}
export const loader: LoaderFunction = async ({ request }) => {
const failFunc = await setCookie(request)
return failFunc.json()
};
export default function Index() {
const data = useLoaderData();
return <div>hi</div>;
}
尝试从 API 路由设置它们也不会工作(从加载器或按钮调用的 app/routes/api/setCookie.tsx - 两者都不起作用)
export let loader: LoaderFunction = () => redirect('/');
export let action: ActionFunction = async ({ request }) => {
const session = await sessionStorage.getSession(
request.headers.get('Cookie')
);
session.set('cookie_example', 'does not work');
return json(
{ status: 'does not work' },
{
headers: {
'Set-Cookie': await sessionStorage.commitSession(session),
},
}
);
};
I have the world's most basic remix app setup to try to figure out createStorageSessionCookies and it seems like they can only be set in the loader of the UI route that is calling the API.
Example:
- Index UI route
- API at routes/api/testApi.tsx (this is a resource route with only an action)
- app/session.server.ts where I create the storage session cookie using createStorageSessionCookies()
If I try to set the cookie anywhere else except for the return from loader in the Index UI route, it doesn't work. If I call the testApi and try to return a response that sets the cookie, doesn't work. If I create a separate function that is called from the loader and that function returns the result of an API call and tries to set the cookie, doesn't work. It literally only works if I set the cookie in the response of the loader.
Example Index route where it works
export const loader: LoaderFunction = async ({ request }) => {
const session = await sessionStorage.getSession(
request.headers.get('Cookie')
);
session.set('cookie_example', 'thisworks');
return json(
{ status: 'this works' },
{
headers: {
'Set-Cookie': await sessionStorage.commitSession(session),
},
}
);
};
export default function Index() {
const data = useLoaderData();
return <div>hi</div>;
}
This won't work
const setCookie = async (request: Request) => {
const session = await sessionStorage.getSession(
request.headers.get('Cookie')
);
session.set('cookie_example', 'thisdoesntwork');
return json(
{ status: 'this doesnt work' },
{
headers: {
'Set-Cookie': await sessionStorage.commitSession(session),
},
}
);
}
export const loader: LoaderFunction = async ({ request }) => {
const failFunc = await setCookie(request)
return failFunc.json()
};
export default function Index() {
const data = useLoaderData();
return <div>hi</div>;
}
Also won't work trying to set them from an API route (app/routes/api/setCookie.tsx called from the loader or from a button - neither work)
export let loader: LoaderFunction = () => redirect('/');
export let action: ActionFunction = async ({ request }) => {
const session = await sessionStorage.getSession(
request.headers.get('Cookie')
);
session.set('cookie_example', 'does not work');
return json(
{ status: 'does not work' },
{
headers: {
'Set-Cookie': await sessionStorage.commitSession(session),
},
}
);
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您正常返回 json() 时,为什么要对 setCookie 函数的响应调用 .json() 呢? https://remix.run/docs/en/v1/api/remix# json
Why are you calling .json() on the response from the setCookie function, when you just return json() normally. https://remix.run/docs/en/v1/api/remix#json
当您在返回 remix
Response
、json
等的函数中提取一些代码时,您不能只返回json(...)
。你必须扔掉它;)检查这里的文档示例: https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders
对于你的最后一个片段,我不会创建一个
loader
这只是重定向
。因为在
action
之后 Remix 会触发loader
。也许它会产生意想不到的行为。如果您想在此操作后重定向,请从按钮提交表单,如下所示:
When you extract some code in function that return remix
Response
,json
etc, you can't just return ajson(...)
. You have to throw it instead ;)Check the doc example here : https://remix.run/docs/en/v1/api/conventions#throwing-responses-in-loaders
And for your last snippet, I would not create a
loader
that justredirect
.Because after an
action
Remix triggersloader
. Maybe it create an unexpected behaviour.If you want to redirect after this action, submit a form from your button like that :