静态生成的站点,覆盖基于会话的信息
Statically generated site, overriding session based info
我的网站基本上是一个静态网站,但我仍然想要身份验证和会话功能。我想象有一种方法可以静态生成网站,但随后会覆盖一些类似你没有登录的消息,以 "user" 身份登录,对吗?更重要的是,它可以与预取一起使用吗?
这部分文档令人困惑:
In other words, any app that involves user sessions or authentication is not a candidate for sapper export.
真正重要的规则是这条:
The basic rule is this: for an app to be exportable, any two users hitting the same page of your app must get the same content from the server.
这并不妨碍您拥有一些代码,对所有用户都相同,但根据客户端会话(例如 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
所承诺的 return 得到解决,以及 (2) 当页面已预取。
如果您打算使用 preload
解析动态内容,重要的是您在服务器中 return 没有任何内容(undefined
或 null
)。否则,如果页面直接被URL访问(比如重新加载同一个页面),那么服务器数据会传递给客户端,preload
不会被称为客户端-边。非常微妙的错误。避开它。
因此,总而言之,服务器中 return 由 preload
编辑的任何内容都将包含在您的静态站点中(因此可公开访问)。但是您仍然可以在客户端管理会话和加载动态内容。如果您从 preload
函数执行此操作,则此加载将照常预取。
我的网站基本上是一个静态网站,但我仍然想要身份验证和会话功能。我想象有一种方法可以静态生成网站,但随后会覆盖一些类似你没有登录的消息,以 "user" 身份登录,对吗?更重要的是,它可以与预取一起使用吗?
这部分文档令人困惑:
In other words, any app that involves user sessions or authentication is not a candidate for sapper export.
真正重要的规则是这条:
The basic rule is this: for an app to be exportable, any two users hitting the same page of your app must get the same content from the server.
这并不妨碍您拥有一些代码,对所有用户都相同,但根据客户端会话(例如 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
所承诺的 return 得到解决,以及 (2) 当页面已预取。
如果您打算使用 preload
解析动态内容,重要的是您在服务器中 return 没有任何内容(undefined
或 null
)。否则,如果页面直接被URL访问(比如重新加载同一个页面),那么服务器数据会传递给客户端,preload
不会被称为客户端-边。非常微妙的错误。避开它。
因此,总而言之,服务器中 return 由 preload
编辑的任何内容都将包含在您的静态站点中(因此可公开访问)。但是您仍然可以在客户端管理会话和加载动态内容。如果您从 preload
函数执行此操作,则此加载将照常预取。