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

Next.js动态博客页面跳转正常,刷新后提示404找不到是什么原因?

问题根因
  • 客户端跳转时走Next.js自带的前端路由逻辑,不会向服务器发起资源请求,能正确匹配blog/[id].js动态路由文件完成渲染;刷新页面时浏览器会直接向服务器请求/blog/对应ID路径的资源,没有对应服务端配置或静态资源的情况下,服务器找不到对应文件就返回404。
  • 如果你的项目采用next export静态导出部署,默认不会为动态路由生成所有ID对应的静态HTML文件,服务器上不存在对应路径的静态资源,是404问题的核心诱因。
  • 代码中直接通过Router.router.query.id获取路由参数的方式不规范,部分场景下路由初始化未完成时可能取不到参数,引发数据请求异常。
解决方案

根据你的项目渲染/部署模式选择对应处理方案即可:

1. 采用SSR服务端渲染部署

只要你用Next.js官方的next start启动Node服务,自带的服务会自动匹配动态路由,不会出现404问题。如果用Nginx做反向代理,只需确保所有请求都转发到Next.js服务:

location / {
  proxy_pass http://127.0.0.1:3000;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
}

2. 采用SSG静态站点生成部署

有两种可选处理方案:

方案A:预生成所有博客静态页

在blog/[id].js中新增getStaticPaths和getStaticProps方法,构建时自动生成所有博客ID对应的静态页面:

// 写在组件代码外部
export async function getStaticPaths() {
  // 调用接口获取全量博客ID列表
  const res = await Api.get('post_list.php')
  const paths = res.data.list.map(item => ({
    params: { id: item.id.toString() }
  }))
  // fallback设为false时,不在列表内的ID直接返回404;设为true时支持动态生成新页面
  return { paths, fallback: false }
}

export async function getStaticProps({ params }) {
  const res = await Api.get(`post.php?id=${params.id}`)
  return {
    props: {
      postData: res.data.data
    },
    revalidate: 86400 // 可选配置,开启增量静态更新,每天自动更新页面内容
  }
}

配置完成后组件内直接通过this.props.postData拿渲染数据即可,不需要再在componentDidMount中发起请求,构建后每个博客ID都会生成对应的静态HTML文件,刷新不会404。

方案B:配置服务端路由重写

如果不想预生成全量页面,在部署用的Web服务器上配置重写规则,把所有/blog/*路径的请求指向/blog/[id].html即可,Nginx配置示例:

location /blog/ {
  try_files $uri $uri.html /blog/[id].html;
}

3. 路由参数获取逻辑优化

不管采用哪种渲染模式,都建议用withRouter高阶组件包裹组件,从props中稳定获取路由参数,修改后的组件代码参考:

import { withRouter } from 'next/router'
import React from 'react'

class Post extends React.Component {
  constructor(props) {
    super(props);  
    this.state={
      data:[],
      loading:true
    }
  }
  async componentDidMount(){
    this.setState({ loading : true })
    // 从props中获取路由参数,稳定性更高
    const id =  this.props.router.query.id;
    const res = await Api.get(`post.php?id=${id}`);
    this.setState({data:res.data.data, loading: false});
  }
  render() {
    return (
      <>
        {/* 原有渲染逻辑 */}
      </>
    )
  }
}

export default withRouter(Post);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:48:03