【问题标题】:How to write into session store during preload如何在预加载期间写入会话存储
【发布时间】:2020-12-15 21:52:06
【问题描述】:

我知道 sapper 中的 session 是一个可写存储。 我可以这样写:

<script>
    import { stores } from "@sapper/app"
    const { session } = stores()
    session.set("new value")
</script>

但是,我很难在预加载函数中写入:

<script context="module">
    export async function preload(page, session) {
        session = "new value" // not working, this is just a value, not a store
    }
</script>

我需要在_layout.svelte 预加载期间在那里设置一些数据。有什么受支持的方法吗?

编辑 我最终根本没有使用会话,只是一个简单的可写存储。它不是那么干净,但它可以达到目的。如果有人找到方法或将来支持它,请将此保持打开状态。

【问题讨论】:

  • 您可以创建自己的session 存储并在preload 中写入。

标签: svelte sapper


【解决方案1】:

这里的session 参数不是会话存储,它是别的东西。它在the docs中被提及:

会话由传递给 sapper.middleware 的会话选项在服务器上生成(TODO 这需要进一步的文档。也许是服务器 API 部分?)

编辑:

[以前的建议因不正确而删除]

为了完整性:session 显然与 session 存储相关,参数是存储的值。但是,您仍然无法以有意义的方式对其进行写入。

就像我在评论中所说的那样,我认为您想要做的事情在preload 中是不可能的。也许我错了,别人可能会告诉你。

同时,我建议以下解决方法:在 _layout 组件 instance 中执行所有这些操作。在那里,您可以完全访问商店。像这样的东西,例如:

<script>
  import { stores } from '@sapper/app'

  import { resolveAuth } from './your/utils'

  const { session } = stores()

  resolveAuth()
    .then(auth => { $session = auth })
    .catch(err => { ... })
</script>

{#if $session}
  <slot />
{:else}
  <!-- loading indicator... or not -->
{/if}

【讨论】:

  • 我正在实现这个 blog.hasura.io/best-practices-of-using-jwt-with-graphql 。确定用户是否登录无法在服务器上完成,因为它依赖于带有 httpOnly cookie 的客户端获取。但我需要在呈现与用户相关的内容之前执行此操作。请问我应该采用不同的方法吗?
  • 好吧,如果你需要在渲染之前等待异步,这对我来说似乎是一个有效的用例。
  • 测试您提供的代码,stores 已定义,但 stores.session 未定义。请注意,我没有对server.js 进行任何更改,所以这可能是原因。
  • 是的,你是对的,我错误地测试了这段代码。您无法从 context=module 脚本中解析存储,而只能在普通(即组件实例)脚本中解析。此外,会话参数只是会话对象的 ,而不是存储,因此您不能对其进行写入。我认为在 preload 函数中不可能做你想做的事情。
  • 好吧,我为您的“认为不可能”的意见投了赞成票,但如果我没记错的话,不幸的是,您的代码与我在问题中提出的代码并没有太大区别。
【解决方案2】:

如前所述,preload 中的会话变量与您的会话存储不同...它们只是碰巧共享相同的名称,并且之所以有效,是因为它们在范围内彼此隔离。

预加载功能——由 sapper 提供——在客户端和服务器上运行,而存储——因为它们是 svelte 的一部分——只存在于客户端上,因此不可能将存储导入预加载我知道。

在我的情况下,在第一次访问我的应用程序时,我想通过使用 HttpOnly cookie 来更新会话(如果客户端已经存在会话)。对我来说,这段代码最明显的地方就是 _layout.svelte 文件。

我的解决方法最终是创建一个 currentSession 变量并将会话数据分配给它,如下所示:

<script context="module">
    export async function preload(page, session) {
        let currentSession = session;
        return { currentSession };
    }
</script>

然后,在我的主脚本标签中

<script>
export let currentSession; // <-- Needs export because it's a prop.
import { session } from '../stores.js';
session.set(currentSession);

// ...Do more stuff...
</script>

这不是最理想的事情——我们都想要——会话变量在导入时已经作为包含会话数据的存储存在,但我猜这是下一个最好的事情。主要的好处是,如果您使用 let session = writeable(null); 之类的东西初始化您的商店,那么当您的组件加载时,$session 将不再是 null

如果您想出更好的方法,请告诉我。谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 2021-06-19
    相关资源
    最近更新 更多