我的网站通常是一个静态网站,但我仍希望使用身份验证和会话功能。我想有一种静态生成站点的方法,但是可以覆盖一些类似您未登录的消息,以便以“用户”的身份登录水合作用吧?更重要的是,它可以与预取一起使用吗?
答案 0 :(得分:0)
这部分文档令人困惑:
换句话说,任何涉及用户会话或身份验证的应用程序都不适合用于sapper导出。
真正重要的规则是这一条:
基本规则是:要使应用程序可导出,点击应用程序同一页面的任何两个用户必须从服务器获取相同内容。
这并不排除您拥有一些对于所有用户都相同的代码,但是根据客户端会话(例如localStorage ...)或您通常可以在客户端上执行的任何操作而有所不同。
例如,您可以在应用中的任何地方都具有这样的代码:
<script>
const isServer = typeof window === 'undefined'
const getUserInfo = async page => {
if (isServer) {
// on server, returns a promise that never resolves, to always
// render as "loading" (adjust to your needs)
return new Promise()
}
// on client, resolve from localStorage, HTTP request, or whatever
return loadUser(page)
}
</script>
{#await getUserInfo()}
<div>Loading...</div>
{:then userInfo}
{#if userInfo && userInfo.userId != null}
<div>Logged in as {userInfo.username}</div>
{:else}
<a href="/login">Log in</a>
{/if}
{:catch err}
<div>Oops: {err}</div>
{/await}
很显然,这不会被预取(Sapper不会分析您的代码做什么)。
但是,您也可以使用以下方法来解析preload
中的用户信息:
<script context="module">
import { loadUser } from './api'
const isServer = typeof window === 'undefined'
export const preload = async page => {
// if preload returns nothing on the server, then it will be called
// again in the client (otherwise the client will be passed the preloaded
// object and preload could be skipped in the client -- see bellow)
if (isServer) return null
const { data } = await loadUser(page)
return { user: data }
}
</script>
<script>
// our user from preload
export let user
</script>
{#if user && !user.anonymous}
<div>Hello, {user.name}</div>
{:else}
<a href="/login">Log in</a>
{/if}
这将产生以下效果:(1)将页面的呈现推迟到preload
返回的承诺得到解决为止;(2)预取页面后开始解析所述用户信息。
如果打算使用preload
解析动态内容,则在服务器中不返回任何内容(undefined
或null
)是很重要的。否则,如果通过URL直接访问该页面(例如,如果您重新加载同一页面),则服务器数据将被传递到客户端,并且preload
不会被称为客户端。非常细微的错误。避免它。
总而言之,服务器中preload
返回的所有内容都将包含在您的静态站点中(因此,可公开访问)。但是您仍然可以管理会话并在客户端中加载动态内容。如果您通过preload
函数执行此操作,则将照常预加载此加载。