You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 基于文件拉取的博客如何实现手动缓存revalidate?

解决方案

你需要的是 Next.js 提供的**按需重验(On-Demand Revalidation)**功能,完全不需要固定时间间隔刷新缓存,只有你主动触发时才会重新拉取posts文件内容生成新页面。

注:按需重验功能需要 Next.js 12.1 及以上版本支持,如果你的项目版本较低需要先升级。


实现步骤

第一步:创建重验API路由

在pages/api目录下新建revalidate.js文件,代码如下:

export default async function handler(req, res) {
  // 建议加密钥校验,防止别人恶意调用重验接口
  if (req.query.secret !== process.env.REVALIDATE_SECRET) {
    return res.status(401).json({ message: '无效的访问权限' })
  }

  try {
    // 这里填你博客页面的路由,博客在首页就填'/',在/blog路径就填'/blog'
    await res.revalidate('/')
    return res.json({ revalidated: true })
  } catch (err) {
    return res.status(500).send('重验失败')
  }
}

你需要在项目环境变量里配置REVALIDATE_SECRET为自定义的密钥,避免接口被滥用。

第二步:修改原有页面的getStaticProps配置

把原来的固定短周期revalidate:60调整为长周期兜底即可,也可以直接删除(删除后只有手动触发才会更新,无兜底刷新):

import path from 'path'
import { promises as fs } from 'fs'

function Blog ({ posts }) {
  return (
    <ul>
      {posts.map((post, key) => (
        <li key={key}>
          <h3>{post.filename}</h3>
          <p>{post.fileContent}</p>
        </li>
      ))}
    </ul>
  )
}

export async function getStaticProps () {
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filenames = await fs.readdir(postsDirectory)

  const posts = filenames.map(async (filename) => {
    const filePath = path.join(postsDirectory, filename)
    const fileContent = await fs.readFile(filePath, 'utf8')
    return { filename, fileContent }
  })

  return {
    props: {
      posts: await Promise.all(posts)
    },
    // 留个一天的长周期作为兜底,也可以删掉这行完全禁用定时重验
    revalidate: 86400
  }
}

export default Blog

第三步:posts目录变动时自动触发重验

你可以通过两种方式实现posts文件改动时自动触发缓存刷新:

  • 本地开发/手动更新场景:用nodemon监听posts目录,文件变动时自动调用重验接口,示例脚本如下:
// 可以存为scripts/watch-posts.js
const nodemon = require('nodemon')
const axios = require('axios')

nodemon({
  watch: './posts',
  ext: 'md markdown txt' // 替换为你实际使用的博客文件后缀
})

nodemon.on('change', async () => {
  try {
    await axios.get('https://你的域名/api/revalidate?secret=你设置的密钥')
    console.log('博客缓存已更新')
  } catch (e) {
    console.log('重验失败', e)
  }
})
  • CI/CD自动部署场景:在你的部署流程里加一步调用重验接口的请求,只要有新的文章提交到仓库,部署完成后自动触发重验即可。

备选方案

如果你的博客更新频率极低,也可以直接删掉revalidate配置,每次新增/修改文章后重新部署整个项目,全量构建生成新的静态页面,也能达到更新内容的效果,缺点是每次更新都需要重新构建,不如按需重验方便。

内容的提问来源于stack exchange,提问作者ozgrozer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:54:03