仅客户端路由和用户身份验证
通常您希望创建一个带有仅客户端部分(允许您通过身份验证来限制访问或根据 URL 参数加载不同内容)的网站。
理解仅客户端路由
一个典型的例子是,一个网站有登陆页、各种营销页面、登录页,然后是一个供已登录用户使用的应用部分。已登录部分不需要服务器渲染,因为在用户登录后,所有数据都将从您的 API 中实时加载。因此,将网站的这部分设置为仅客户端是有意义的。
仅客户端路由仅存在于客户端,并且不会在应用程序构建的 /public 目录下的 index.html 文件中有所体现。如果您希望网站用户能够直接访问仅客户端路由,您需要 相应地设置您的网站来处理这些路由。或者,如果您自己控制文件服务器的配置,您可以 设置服务器 来处理这些路由。
一个示例网站可能设置如下
Gatsby 将 pages 文件夹中的组件转换为主页和应用页面的静态 HTML 文件。一个 <Router /> 被添加到应用页面,以便个人资料和详细信息组件可以从应用页面渲染;它们没有为它们构建静态资源,因为它们只存在于客户端。个人资料页面可以将用户的 POST 数据发送回 API,而详细信息页面可以从 API 动态加载特定 id 的用户数据。
处理 Gatsby 的仅客户端路由
Gatsby 在底层使用 @reach/router,因此我们将使用它来在我们的应用程序中设置仅客户端路由。
您首先需要在一个由 Gatsby 构建的页面上设置路由。您可以在下面的代码示例中看到添加到 src/pages/app/[...].js 的路由
简而言之,当一个页面加载时,Reach Router 会查看嵌套在 <Router /> 下的每个组件的 path 属性,并选择 一个 来渲染,该组件最匹配 window.location(您可以从 @reach/router 文档 中了解更多关于路由工作原理的信息)。对于 /app/profile 路径,将渲染 Profile 组件,因为它的前缀匹配 /app 的基本路径,剩余部分与子路由的路径相同。
调整路由以适应已登录用户
通过在您的网站上 设置身份验证,您可以创建一个像 <PrivateRoute/> 这样的组件来扩展上面的示例并限制对内容的访问
上面的 <PrivateRoute /> 组件看起来会是这样的(摘自 身份验证教程,它实现了这个行为)
提示:对于复杂的路由应用程序,您可能希望使用 shouldUpdateScroll 浏览器 API 来覆盖 Gatsby 的默认滚动行为。
如何配置您的托管服务来处理仅客户端路由
网站托管软件和服务需要一些帮助才能正确地提供仅客户端路由。大多数 Gatsby 页面都有一个对应的 html 文件,当用户访问页面时,服务器会响应该文件,例如访问 /blog/my-blog-post/ 会使服务器响应 /blog/my-blog-post/index.html。但像 /app/why-gatsby-is-awesome/ 这样的仅客户端路由没有对应的 html 文件。服务器需要被配置成知道响应 /app/[...]/index.html 来代替。
像 Gatsby Cloud、Netlify 和 Vercel 这样的流行托管服务都有插件,可以自动配置托管以处理仅客户端路由。
- Gatsby Cloud
- Netlify
- Vercel 会自动添加其 Gatsby 插件。
使用 NGINX 和 Apache 自行托管
您的服务器配置应使用 /app/[...]/index.html 来处理对 /app/* 的 GET 请求,例如 /app/why-gatsby-is-awesome,并让客户端处理匹配路径的路由渲染。需要注意的是,响应代码应该是 200(成功),而不是 301(重定向)。这可以通过 NGINX 使用 try_files 指令来完成,或者在使用 Apache 时使用 等效指令。
附加资源
- Gatsby 仓库“simple auth”示例 - 一个演示实现用户身份验证和受限的仅客户端路由的示例
- “simple auth”示例的实时版本
- Gatsby 商店,也实现了身份验证流程