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

NuxtJS博客刷新详情页参数失效,触发读取author属性报错

问题原因分析与解决方案

首先咱们来拆解一下你遇到的问题:

核心原因:路由参数不匹配 + 刷新时隐式参数丢失

你通过nuxt-link跳转时传递了id参数,但你的路由category-slug的路径结构是/:category/:slug(从刷新后的URLtech/hello-world能看出来)——这个路由路径里并没有id这个动态段。

  • 首次通过nuxt-link跳转属于客户端导航,Nuxt会把你传入的所有参数(包括id)暂时存在内存里,所以context.params.id能拿到值,请求正常。
  • 但刷新页面时,浏览器只会把URL中实际存在的参数(也就是category和slug)传给应用,id这个没出现在URL里的参数直接丢失了,导致context.params.id变成undefined。这时候你的axios请求就变成了:
    axios.get('https://howto-a9089.firebaseio.com/posts/undefined.json')
    
    后端返回null,你再访问loadedPost.author自然就抛出Cannot read property 'author' of null的错误。

针对性解决方案

方案1:把id加入路由路径(URL显式携带)

修改路由配置,让id成为URL的一部分,比如把路由路径改成/:category/:slug/:id。这样刷新页面时,id会作为URL的一部分被保留,context.params.id就能稳定获取到值。

对应的nuxt-link可以保持不变,刷新后的URL会变成类似tech/hello-world/123。

方案2:通过category+slug获取文章数据

如果不想修改URL结构,可以调整后端接口,支持通过category和slug查询文章。这样在asyncData里就可以用这两个参数请求数据:

asyncData(context) {
  const { category, slug } = context.params
  return axios.get(`https://howto-a9089.firebaseio.com/posts/${category}/${slug}.json`)
    .then(res => {
      return { loadedPost: res.data }
    })
}

不管是首次跳转还是刷新,都能拿到有效的参数,请求到正确的文章数据。

方案3:用查询参数(query)传递id

如果必须依赖id,可以把id作为查询参数传递,而不是路由params:

<nuxt-link :to="{
  name: 'category-slug',
  params: { slug: slug, category: category },
  query: { id: id }
}">

然后在asyncData里通过context.query.id获取:

asyncData(context) {
  const postId = context.query.id
  if (!postId) {
    // 处理id不存在的情况,比如重定向到404
    context.redirect('/404')
    return { loadedPost: {} }
  }
  return axios.get(`https://howto-a9089.firebaseio.com/posts/${postId}.json`)
    .then(res => {
      return { loadedPost: res.data }
    })
}

刷新后URL会变成tech/hello-world?id=123,查询参数会被保留,id就能正常获取。

额外建议:添加错误处理

不管用哪种方案,都建议在asyncData里添加错误处理,避免请求失败导致页面崩溃:

asyncData(context) {
  const postId = context.query.id // 或者对应的参数
  if (!postId) {
    context.redirect('/404')
    return { loadedPost: {} }
  }
  return axios.get(`https://howto-a9089.firebaseio.com/posts/${postId}.json`)
    .then(res => {
      if (!res.data) {
        // 文章不存在的情况
        context.redirect('/404')
        return { loadedPost: {} }
      }
      return { loadedPost: res.data }
    })
    .catch(err => {
      console.error('请求文章失败:', err)
      context.redirect('/404')
      return { loadedPost: {} }
    })
}

内容的提问来源于stack exchange,提问作者Flæx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:14:13