Next.js高级特性:预览模式

在Pages文档和Data Fetching文档中,我们讨论了如何使用和在构建时预渲染页面(静态生成)。getStaticPropsgetStaticPaths

当页面从无头CMS提取数据时,“静态生成”很有用。但是,当您在无头CMS上编写草稿并希望立即在页面上预览草稿时,这是不理想的。您希望Next.js在请求时而不是在构建时呈现这些页面,并获取草稿内容而不是已发布的内容。您只希望Next.js在这种情况下绕过Static Generation。

Next.js具有称为“预览模式”的功能,可以解决此问题。以下是有关如何使用它的说明。

步骤1.创建和访问预览API路线

如果您不熟悉Next.js API路由,请先查看API路由文档。

首先,创建一个预览API路线。它可以具有任何名称-例如pages/api/preview.js(或.ts使用TypeScript)。

在此API路由中,您需要调用setPreviewData响应对象。for的参数setPreviewData应该是一个对象,并且可以使用getStaticProps(稍后会有更多介绍)。现在,我们将使用{}

export default function handler(req, res) {
  // ...
  res.setPreviewData({})
  // ...
}

res.setPreviewData在打开预览模式的浏览器上设置一些cookie。对包含这些cookie的对Next.js的任何请求都将被视为预览模式,并且静态生成的页面的行为将发生变化(稍后会对此进行更多介绍)。

您可以通过创建如下所示的API路由并从浏览器手动访问它来手动进行测试:

// A simple example for testing it manually from your browser.
// If this is located at pages/api/preview.js, then
// open /api/preview from your browser.
export default function handler(req, res) {
  res.setPreviewData({})
  res.end('Preview mode enabled')
}

如果使用浏览器的开发人员工具,您会注意到,将在此请求上设置__prerender_bypass__next_preview_datacookie。

从您的Headless CMS安全地访问它

实际上,您希望从无头CMS安全地调用此API路由。具体步骤会因您所使用的无头CMS而有所不同,但这是您可以采取的一些常见步骤。

这些步骤假定您使用的无头CMS支持设置自定义预览URL。如果不是这样,您仍然可以使用此方法来保护预览URL,但是您需要手动构造和访问预览URL。

首先,您应该使用所选的令牌生成器创建秘密令牌字符串。仅您的Next.js应用和无头CMS才知道此秘密。此秘密可防止无权访问您的CMS的人访问预览URL。

其次,如果您的无头CMS支持设置自定义预览URL,请指定以下内容作为预览URL。(这假设您的预览API路由位于pages/api/preview.js。)

https://<your-site>/api/preview?secret=<token>&slug=<path>
  • <your-site> 应该是您的部署域。
  • <token> 应该替换为您生成的秘密令牌。
  • <path>应该是您要预览的页面的路径。如果要预览/posts/foo,则应使用&slug=/posts/foo

您的无头CMS可能允许您在预览URL中包含一个变量,以便<path>可以根据CMS的数据进行动态设置,如下所示:&slug=/posts/{entry.fields.slug}

最后,在预览API路线中:

  • 检查密码是否匹配以及slug参数是否存在(如果不存在,则请求将失败)。
  • 致电res.setPreviewData
  • 然后将浏览器重定向到所指定的路径slug。(以下示例使用307 redirect)。
export default async (req, res) => {
  // Check the secret and next parameters
  // This secret should only be known to this API route and the CMS
  if (req.query.secret !== 'MY_SECRET_TOKEN' || !req.query.slug) {
    return res.status(401).json({ message: 'Invalid token' })
  }

  // Fetch the headless CMS to check if the provided `slug` exists
  // getPostBySlug would implement the required fetching logic to the headless CMS
  const post = await getPostBySlug(req.query.slug)

  // If the slug doesn't exist prevent preview mode from being enabled
  if (!post) {
    return res.status(401).json({ message: 'Invalid slug' })
  }

  // Enable Preview Mode by setting the cookies
  res.setPreviewData({})

  // Redirect to the path from the fetched post
  // We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
  res.redirect(post.slug)
}

如果成功,则将浏览器重定向到要设置预览模式Cookie的预览路径。

步骤2.更新 getStaticProps

下一步是更新getStaticProps以支持预览模式。

如果您请求的页面getStaticProps设置了(通过res.setPreviewData)设置了预览模式Cookie ,则将getStaticProps请求时(而不是在构建时)调用该页面。

此外,将使用以下context对象调用该对象:

  • context.preview会的true
  • context.previewData将与用于的参数相同setPreviewData
export async function getStaticProps(context) {
  // If you request this page with the preview mode cookies set:
  //
  // - context.preview will be true
  // - context.previewData will be the same as
  //   the argument used for `setPreviewData`.
}

我们res.setPreviewData({})在预览API路由中使用过,因此context.previewData将是{}getStaticProps如有必要,您可以使用它来将会话信息从预览API路由传递到。

如果您还使用getStaticPaths,则context.params也将可用。

获取预览数据

您可以getStaticProps基于context.preview和/或更新以获取不同的数据context.previewData

例如,您的无头CMS可能具有不同的草稿帖子API端点。如果是这样,您可以使用context.preview来修改API端点URL,如下所示:

export async function getStaticProps(context) {
  // If context.preview is true, append "/preview" to the API endpoint
  // to request draft data instead of published data. This will vary
  // based on which headless CMS you're using.
  const res = await fetch(`https://.../${context.preview ? 'preview' : ''}`)
  // ...
}

就是这样!如果您从无头CMS或通过手动访问预览API路由(使用secretslug),则现在应该可以看到预览内容。而且,如果您在不发布的情况下更新草稿,则应该能够预览草稿。

# Set this as the preview URL on your headless CMS or access manually,
# and you should be able to see the preview.
https://<your-site>/api/preview?secret=<token>&slug=<path>

更多细节

清除预览模式的Cookie

默认情况下,没有为预览模式Cookie设置有效期,因此,关闭浏览器时,预览模式结束。

要手动清除预览cookie,您可以创建一个调用的API路由,clearPreviewData然后访问该API路由。

export default function handler(req, res) {
  // Clears the preview mode cookies.
  // This function accepts no arguments.
  res.clearPreviewData()
  // ...
}

指定预览模式的持续时间

setPreviewData接受一个可选的第二个参数,该参数应该是一个options对象。它接受以下密钥:

  • maxAge:指定预览会话要持续的时间(以秒为单位)。
setPreviewData(data, {
  maxAge: 60 * 60, // The preview mode cookies expire in 1 hour
})

previewData 大小限制

您可以将对象传递给setPreviewData并在中使用它getStaticProps。但是,由于数据将存储在Cookie中,因此存在大小限制。当前,预览数据限制为2KB。

适用于 getServerSideProps

预览模式也适用getServerSideProps。它也将在context包含preview和的对象上可用previewData

使用API​​路由

API路由将有权访问请求对象previewpreviewData在该对象下。例如:

export default function myApiRoute(req, res) {
  const isPreview = req.preview
  const previewData = req.previewData
  // ...
}

Unique per next build

完成时,绕过cookie值和用于加密previewData更改的私钥都将next build被使用。这样可以确保无法猜测旁路cookie。

作者:terry,如若转载,请注明出处:https://www.web176.com/nextjs/2447.html

(0)
打赏 支付宝 支付宝 微信 微信
terryterry
上一篇 2021年4月20日 下午3:13
下一篇 2021年4月20日 下午4:14

相关推荐

发表回复

登录后才能评论
nic porn hdmovz.mobi omansex
my sexy savita tubster.net oral sex mms
sexy hollywood movies thempeg.mobi zulu reed dance bathing
صور سكس ليلى علوى wahmbahm.com نيك اسكندراني
indian outdoor xnxx hdtporno.org bollywood actress xvideo
latest xvideos whiteporntube.info sexy gand mari
سكس جد teenagesexvids.com فيلم جنسى كامل
www.desi xb.com cumshotporntrends.com www indian sex con
indian style fucking pornodon.net kamwali bai
سكس اخ ينيك اختو noodporn.com سكس امهات وصبى
3gp sex.com hindipornmovies.org namitha bf videos
سكس هواه ounoun.com افلام اغتصاب مترجمة
you tube8 pornvideox.mobi desi sex videos download
سكس بنات مع كلاب xltcf.com سكس مصري مخفي
indian mobil sex nudeindiantube.net xvideos.tamil