uni-app 路由模式 history 在 SSR 方式发行时报错 Hydration completed but contains mismatches

发布于 1周前 作者 phonegap100 来自 Uni-App

uni-app 路由模式 history 在 SSR 方式发行时报错 Hydration completed but contains mismatches

操作步骤:

  • 发行 -> 网站PC -> 勾选 以SSR方式发行,将编译后资源部署到前端网页托管

预期结果:

  • 部署后正常预览

实际结果:

  • 页面不展示,有报错信息【Hydration completed but contains mismatches.】

bug描述:

【重要】
新拉的项目 用的uni-app的模板 选的vue3, history模式部署后,还是会报错

相关链接:

图片

Image


1 回复

在使用 uni-app 进行 SSR(Server-Side Rendering)发行时,如果路由模式设置为 history,并且出现 Hydration completed but contains mismatches 的错误,通常是由于客户端和服务器端渲染的内容不一致导致的。这种问题在 SSR 中比较常见,尤其是在路由处理、异步数据获取或动态内容渲染时。

以下是一些可能的原因和解决方案:


1. 路由模式问题

  • 原因history 模式在 SSR 中需要服务器端进行正确的路由处理,否则可能导致客户端和服务器端渲染的内容不一致。
  • 解决方案
    • 确保服务器端配置了正确的路由处理逻辑,支持 history 模式。
    • 如果使用 nginx,可以添加以下配置:
      location / {
          try_files $uri $uri/ /index.html;
      }
    • 如果使用 express,可以添加以下中间件:
      const express = require('express');
      const path = require('path');
      const app = express();
      
      app.use(express.static(path.join(__dirname, 'dist')));
      
      app.get('*', (req, res) => {
          res.sendFile(path.join(__dirname, 'dist', 'index.html'));
      });
      
      app.listen(3000, () => {
          console.log('Server is running on port 3000');
      });

2. 异步数据获取问题

  • 原因:如果页面依赖异步数据(如 API 请求),而服务器端和客户端获取的数据不一致,会导致 Hydration 不匹配。
  • 解决方案
    • 确保服务器端和客户端使用相同的异步数据获取逻辑。
    • uni-app 中,可以使用 onServerPrefetch 钩子在服务器端预取数据:
      export default {
          async onServerPrefetch() {
              // 在服务器端预取数据
              await this.fetchData();
          },
          methods: {
              async fetchData() {
                  // 获取数据的逻辑
              }
          }
      };
    • 确保客户端在 mountedcreated 钩子中获取相同的数据。

3. 动态内容问题

  • 原因:如果页面内容依赖于动态数据(如用户信息、时间戳等),而服务器端和客户端渲染的内容不一致,会导致 Hydration 不匹配。
  • 解决方案
    • 避免在渲染过程中使用动态数据(如 Date.now()Math.random())。
    • 如果必须使用动态数据,确保服务器端和客户端使用相同的值。

4. 环境差异问题

  • 原因:服务器端和客户端的运行环境可能不同(如 window 对象在服务器端不存在),导致渲染结果不一致。
  • 解决方案
    • 在代码中检查运行环境,避免在服务器端使用客户端特有的 API(如 windowdocument)。
    • 使用 process.clientprocess.server 判断当前环境:
      if (process.client) {
          // 仅在客户端执行的代码
      }
      if (process.server) {
          // 仅在服务器端执行的代码
      }
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!