使用 Next.js 中的 getStaticProps 对 public 文件夹中的静态图像进行编码
Encoding static imagery from public folder using getStaticProps in Next.js
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,
};
}
此代码有效,但当我在我的组件中引用该对象时,它 returns 一个非常奇怪的响应:
<img src="{ "type":"Buffer", "data":[255,216,255,224,0,6,75,56,86,87,...] } />
我的错误与我处理 fs
返回的内容的方式有关。我是否需要将我的 jpeg 编码为 base64
才能让 Next 使用它? This answer suggests stringifying and then parsing (didn't work for me). Or maybe I need a 要做到这一点?接下来不是很清楚如何从 getStaticProps 获取 imagery 到它上面的组件 - 也许你知道怎么做?
从 getStaticProps
中 return 编辑的所有数据都需要 JSON 可序列化,所以是的,如果你想在那里 return 图像,你需要base64 对其进行编码(这对于大图像来说可能是个问题)。
另一种解决方案(如果情况允许)不是使用 getStaticProps
而是在前端按需加载图像,方法是在页面加载后点击 API。
我最终为 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}`)
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,
};
}
还要确保在组件中,您正确地将图像源编码为带有 data:image/png;base64,
前缀的 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 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,
};
}
此代码有效,但当我在我的组件中引用该对象时,它 returns 一个非常奇怪的响应:
<img src="{ "type":"Buffer", "data":[255,216,255,224,0,6,75,56,86,87,...] } />
我的错误与我处理 fs
返回的内容的方式有关。我是否需要将我的 jpeg 编码为 base64
才能让 Next 使用它? This answer suggests stringifying and then parsing (didn't work for me). Or maybe I need a
从 getStaticProps
中 return 编辑的所有数据都需要 JSON 可序列化,所以是的,如果你想在那里 return 图像,你需要base64 对其进行编码(这对于大图像来说可能是个问题)。
另一种解决方案(如果情况允许)不是使用 getStaticProps
而是在前端按需加载图像,方法是在页面加载后点击 API。
我最终为 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}`)
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,
};
}
还要确保在组件中,您正确地将图像源编码为带有 data:image/png;base64,
前缀的 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
模板,则生成的每个页面的所有资产都将计入该上限。你会在部署时很快地击中它,所以仔细检查你自己。