4

我无法让 Sapper 在没有页面加载的情况下同步在我的服务器端路由中所做的会话更改。我的示例场景是我在会话中没有用户的情况下加载我的应用程序,我的服务器端登录路由将用户设置为会话,然后我使用goto它来访问仪表板。

问题是session仪表板的预加载函数中的参数未填充。如果我使用window.location.href = '/dashboard',它是,因为它通过 Sapper 的page_handler运行。但是,如果我只进行客户端重定向,Sapper 不会将更新的会话发送到客户端。

有什么办法吗?我用错工具了吗?

注意:我正在使用 connect-pg-simple 和 express-session,像这样设置 sapper sapper.middleware({session: (req, res) => req.session.public}):.

4

2 回答 2

2

我在Sapper 文档中找到了答案

session包含在服务器上播种的任何数据。它是一个可写存储,这意味着您可以使用新数据对其进行更新(例如,在用户登录后)并且您的应用程序将被刷新。

从字里行间看,这表明您的应用程序必须手动同步您的会话数据。

这里的解决方案是手动将会话数据同步到客户端,可以使用 webhook 连接、响应标头或响应数据中的键。

我有一个装饰器,用于创建服务器路由处理程序,在其中我将会话数据添加到响应中。这是一个简化版本:

const createHandler = getData => (req, res) => {
  res.status(200).json({data: getData(req.body), session: req.session.public})
}

显然,它的功能远不止这些,例如错误处理,但你明白了。在客户端,我包装fetch了一个帮助函数,无论如何我总是使用它来获取我的 json,设置正确的标头等。在其中,我查看响应,如果有session属性,我将其设置为会话存储所以它在我preload的 s 中可用。

import {stores} from "@sapper/app"

const myFetch = (...args) => fetch(...args).then(r => r.json()).then(body => {
  if (body.session) stores().session.set(body.session)

  return body.data
})
于 2019-08-15T18:25:32.370 回答
0

简而言之,在您的会话状态从前端更改后(用户刚刚登录,或者您刚刚使他的登录无效),您应该更新前端的会话存储。

<script>
  import { goto, stores } from '@sapper/app';
  const { session } = stores();

  const loginBtnHandler = () => {

    const req = await fetch('/api/login', {
      method: 'POST',
      credentials: 'same-origin', // (im using cookies in this example)
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ ........ })
   });

   if (req.ok) {
     // here is where you refresh the session on the client right after you log in
     $session.loggedIn = true; // or your token or whatever

     // next page will properly read the session
     goto('/');

     return;
   }

   ...

  }
</script>
于 2021-01-08T18:33:18.837 回答