使用 Next.js 中的 getStaticProps 对公用文件夹中的静态图像进行编码

Posted

技术标签:

【中文标题】使用 Next.js 中的 getStaticProps 对公用文件夹中的静态图像进行编码【英文标题】:Encoding static imagery from public folder using getStaticProps in Next.js 【发布时间】:2021-08-21 19:15:26 【问题描述】:

Next.js lays out a pretty comprehensive way 从/public/ 文件夹(应用程序存储静态资产的位置)获取图像。模式是使用 Node 中的 fs 并在 getStaticProps 中进行提取。

我的尝试:

export async function getStaticProps( params, preview = false, previewData ) 
  const cityData = dataFiltered.find( city => city.citySlug === params.slug )
  const cityMapImagePath = path.join(process.cwd(), `/public/static-maps/$cityData.imgPath`)
  const cityMapImageRes = await fs.readFile(cityMapImagePath)
  const cityMapImageProcessed = JSON.stringify(cityMapImageRes)

  return 
    props: 
      preview,
      cityData: cityData,
      cityMapImage: cityMapImageProcessed
    ,
    revalidate: 60,
  ;

此代码有效,但当我在组件中引用该对象时,它会返回一个非常奇怪的响应:

<img src=" "type":"Buffer", "data":[255,216,255,224,0,6,75,56,86,87,...]  />

我的错误与我如何处理 fs 给我的信息有关。我是否需要将我的 jpeg 编码为 base64 才能让 Next 使用它? This answer 建议进行字符串化然后解析(对我不起作用)。或者也许我需要一个full blown endpoint 来做到这一点?接下来不太清楚如何将 imagery 从 getStaticProps 获取到它上面的组件中——也许你知道怎么做?

【问题讨论】:

【参考方案1】:

getStaticProps 返回的所有数据都需要是 JSON 可序列化的,所以是的,如果你想在那里返回图像,你需要对它进行 base64 编码(这对于大图像来说可能是个问题)。 另一种解决方案(如果场景允许)不是使用getStaticProps 来执行此操作,而是通过在页面加载后点击 API 在前端按需加载图像。

【讨论】:

谢谢,这让我思路清晰。我想我有两个问题,不是在 Base64 中编码,然后没有在我的 img src 前加上 base64 编码。我将在下面发布完整的答案。【参考方案2】:

我最终为 getStaticProps 中的 fetch 做了什么:

export async function getStaticProps( params, preview = false, previewData ) 
  const cityData = dataFiltered.find( city => city.citySlug === params.slug )
  const cityMapImagePath = path.join(process.cwd(), `/public/static-maps/$cityData.imgPath`)
  let cityMapImageRes, cityMapImageProcessed

  try 
    cityMapImageRes = await fs.readFile(cityMapImagePath)
    cityMapImageProcessed = Buffer.from(cityMapImageRes).toString('base64')
   catch 
    cityMapImageProcessed = null
  

  return 
    props: 
      preview,
      cityData: cityData,
      cityMapImage: cityMapImageProcessed
    ,
    revalidate: 60,
  ;

还要确保在组件中,您正确地将图像源编码为 base64 并带有 data:image/png;base64, 前缀。这是一个愚蠢的错误,花了我一个小时的调试时间:

<img src=`data:image/png;base64,$cityMapImage` alt='Alt text here' />

最后,还要注意,Next.js 与 Vercel 一起使用时会施加一个硬的 50MB cap (compressed) on the serverless function 用于处理您的 page 文件请求。如果您正在使用[slug].js 模板,则生成的每个页面的所有资产都将计入该上限。您会在部署时很快达到目标,因此请仔细检查自己。

【讨论】:

以上是关于使用 Next.js 中的 getStaticProps 对公用文件夹中的静态图像进行编码的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Next.js 中的 next/image 渲染未知尺寸的图像?

next.js 中的 apollo-client 与 `next-with-apollo` VS next.js 文档常见问题解答中显示的方法(不使用 `getDataFromTree`)

Next.js 配置文件中的 next/image 配置

Vercel 中的 Next.js 与 Sentry - 在生产中忽略源映射

使用 Next.js 中的 getStaticProps 对公用文件夹中的静态图像进行编码

Next.js 中的会话管理