Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Session Sapper/svelte3会话在没有页面重新加载的情况下不同步_Session_Sapper_Svelte 3 - Fatal编程技术网

Session Sapper/svelte3会话在没有页面重新加载的情况下不同步

Session Sapper/svelte3会话在没有页面重新加载的情况下不同步,session,sapper,svelte-3,Session,Sapper,Svelte 3,我无法让Sapper在没有页面加载的情况下同步服务器端路由中所做的会话更改。我的示例场景是,我在会话中没有用户的情况下加载应用程序,我的服务器端登录路由将用户设置为会话,我使用goto进入仪表板 问题是没有填充仪表板预加载函数中的会话参数。如果我使用的是window.location.href='/dashboard',它就是,因为它正在Sapper的应用程序中运行。但是如果我只重定向客户端,Sapper不会将更新的会话发送到客户端 有办法吗?我用错工具了吗 注意:我正在使用connectpgs

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

问题是没有填充仪表板预加载函数中的
会话
参数。如果我使用的是
window.location.href='/dashboard'
,它就是,因为它正在Sapper的应用程序中运行。但是如果我只重定向客户端,Sapper不会将更新的会话发送到客户端

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

注意:我正在使用connectpgsimple和express会话,设置sapper如下:
sapper.middleware({session:(req,res)=>req.session.public})

我在

会话
包含服务器上的种子数据。它是一个可写存储,这意味着您可以使用新数据更新它(例如,在用户登录后),您的应用程序将被刷新

这表明你的应用程序必须手动同步你的会话数据

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

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

const createHandler = getData => (req, res) => {
  res.status(200).json({data: getData(req.body), session: req.session.public})
}
很明显,还有更多,例如错误处理,但你明白了。在客户机上,我将
fetch
包装在一个helper函数中,我总是使用该函数来获取json、设置正确的头等等。在该函数中,我查看响应,如果有
session
属性,我将其设置到会话存储中,以便在
preload
中可用

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
})

简单地说,在您的会话状态从前端更改后(用户刚刚登录,或者您刚刚使其登录无效),您应该更新前端上的会话存储

<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>

从'@sapper/app'导入{goto,stores};
const{session}=stores();
const loginBtnHandler=()=>{
const req=wait fetch('/api/login'{
方法:“POST”,
凭证:'相同来源',//(本例中我使用cookie)
标题:{
“内容类型”:“应用程序/json”,
},
正文:JSON.stringify({……..})
});
如果(请求ok){
//在这里,您可以在登录后立即刷新客户端上的会话
$session.loggedIn=true;//或您的令牌或其他
//下一页将正确阅读会话
后藤(“/”);
返回;
}
...
}

谢谢您的回答。我有点理解你的答案,但我无法通过预加载来传递数据。您是否介意发布一个预加载“export async function preload(){}的示例,以查看如何在stores()中设置会话?这是一个大问题,我看到不止一个帖子请求帮助,但没有人提供帮助。似乎rich是唯一回答这个问题的人,我们需要一个可行的例子。不幸的是,我无法使预加载工作正常进行(会话是问题的一部分,我认为还有其他问题),因此我没有工作示例。回答得很好,谢谢。请看: