动态 API 调用如何在 Nuxt.js 静态与 SSR 模式下工作?

How do dynamic API calls work in Nuxt.js static vs SSR mode?

即使阅读了多篇解释静态渲染和 SSR 渲染之间差异的文章,我仍然不明白动态 API 调用在这些不同模式下是如何工作的。

我知道 Nuxt 有 fetchasyncData 钩子,它们在静态生成期间只调用一次,但是如果我在组件方法中使用动态 HTTP 请求怎么办(例如,当通过POST 请求)?这甚至适用于静态网站吗?

我正在制作一个在大多数页面上显示用户生成内容的网站,因此每次访问其中一个页面时我都必须发出 GET 请求以保持内容是最新的。我可以使用静态站点来做到这一点,还是必须使用 SSR / 其他东西?我不想使用客户端呈现(SPA 模式),因为它很慢而且对 SEO 不利。那么我最好的选择是什么?

I use dynamic HTTP requests inside component methods (e.g. when submitting a form via a POST request)? Does that even work in static sites?

这个问题的简短回答是,是的,它确实有效。事实上,您可以在代码中的任何生命周期挂钩或方法中使用 http 请求,并且它们都可以在静态模式下正常工作。

Nuxt.js 中的静态站点生成和 ssr 模式是帮助您解决 SEO 问题的工具,我将通过示例解释它们的区别。

假设您在 url 有一个博客 post 页面,类似于 coolsite.com/blogs,其中一些 post 来自数据库。

SPA

在这种模式下,当用户访问所述URL 服务器时,基本上会以.js 文件作为响应,然后在客户端中将呈现此.js 文件。创建一个 Vue 实例,当应用程序到达 created 挂钩中的 get posts 请求的代码时,它会进行 API 调用,获取结果并呈现 posts 到 DOM.

这对 SEO 来说并不酷,因为在第一次加载应用程序时没有任何内容,而且所有搜索引擎网络爬虫都更擅长将内容理解为 html 而不是 js。

SSR

在此模式下,如果您使用 asyncData 挂钩,当用户请求上述 URL 时,服务器 运行s asyncData 挂钩中的代码,您应该在其中包含您的 API 征集博客 posts。它获取结果,将其呈现为 html 页面,并将其与其中已有的内容一起发送回用户(Vue 实例仍会在客户端中创建)。不需要从客户端到服务器的任何进一步请求。当然,您仍然可以 api 在其他方法或挂钩中调用。

此处的缺点是您需要某种部署方式才能使其正常工作,因为代码必须 运行 在服务器上。例如,您需要 node.js 虚拟主机来 运行 服务器上的应用程序。

静态

这个模式实际上是前两者的折衷。这意味着您可以拥有静态网络托管,但仍然可以使您的应用程序更好地进行 SEO。

它的工作方式很简单。您再次使用 asyncData,但在这里,当您在本地机器上生成应用程序时,它 运行s asyncData 中的代码,获取 posts,然后为每个呈现正确的 html您的应用程序路线。因此,当您部署并且用户请求 URL 时,she/he 将获得呈现的页面,就像 SSR 模式下的页面一样。

但这里的缺点是,如果您将 post 添加到您的数据库,您需要在您的本地计算机上生成您的应用程序,并使用新生成的文件更新您服务器上所需的文件为了让用户得到最新的内容。

除此之外,任何其他 API 调用都可以正常工作,因为为此所需的代码已经发送给客户端。

旁注:我在我的示例中使用了 asyncData,因为这是您应该在页面级别使用的挂钩,但 fetch 也是一个 Nuxt.js 挂钩,它在组件级别的工作方式大致相同。

当您使用 target: static(SSG)或 target: server(默认,SSR)时,asyncData()fetch() 挂钩实际上没有区别。
至少,不在您的用例中。

它们主要由您的水化应用程序使用。
提醒一下,当使用 SSG 或 SSR 时,您的静态页面将被水化并成为一个具有我们喜欢的所有动态功能的 SPA。 SSG + SPASSR + SPA 的组合称为 通用应用程序 (或 同构应用程序 )。

asyncData()fetch() 都将在您的客户端 SPA 中导航时被调用。


服务器端也发生了一些事情,例如当您向服务器请求 SSR 构建的应用程序时 fetch 被调用 (by default)。

或者当您生成应用程序(如果使用 SSG)时,您可以访问一些 API 并生成动态路由(例如在无头 CMS + 博客组合的情况下很有用)。
出于性能原因和快速构建时间,您可以传递 payload 并在动态路由的 asyncData 挂钩中使用它,如 here

所述

仍然,静态 Nuxt 应用程序基本上只是一个 app built ahead of time, with no need for a Node.js server,因此为什么 SSG 应用程序可以免费托管在 Netlify (CDN) 上,而 SSR 应用程序需要托管在 Heroku 之类的东西上(在付费 VPS).

这里要问自己的主要问题是:

  • 您需要保护某些内容吗?像一些视频课程、私人用户信息等......已经在你的 Nuxt 项目中(如果是 SSG,禁用 JS 将允许访问生成的内容)
  • 您的第一页是登录吗?是否必须访问其余内容?就像一个管理仪表板(如果数据是私有的,你不能提前生成内容,想想 Facebook 的 feed 是为每个帐户生成的,如上所述不可行且不安全)
  • 我的 API 更新是否非常频繁,我是否需要一些超快速的构建时间(本质上是免费层的限制)? (每次 API 更改时 SSG 都需要重新生成)

如果其中 none 个是相关的,你完全可以去 SSG。
如果其中一个对你很重要,你可以考虑SSR。


我确实建议尝试所有这些:

  • SSR (ssr: true + target: server) 与 yarn build && yarn start
  • SSG (ssr: true + target: static) 与 yarn generate && yarn start
  • 仅 SPA(ssr: false + target: statictarget: server 也可以,但谁愿意为 SPA 付费?!)与 yarn generate && yarn start

如果您想确保了解本地构建之外的差异,也请尝试在某些平台上托管它。
您还可以使用此 kind of extension 来仔细检查是否启用 JS 的行为。

我可能会推荐走SSG这条路。即使如此,如果您的内容总是在变化,您可能不会从 SEO 中获益太多(例如:TwitterFacebook)。

这个 github answer 也许可以帮助您更好地理解事情(它确实有一些来自 Atinux 的视频)。


PS:我在最新的 Nuxtnation 上做了一个关于这个的视频,你可以 find here