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

Fastify升级后EJS渲染MongoDB数据页面白屏无报错解决方法

问题描述

个人网站开发过程中,基于MongoDB的数据库模块已接近完成,升级Fastify相关依赖后,所有传入数据渲染的EJS页面均显示空白,控制台无任何报错输出,无法定位故障点。
当前项目依赖版本:

  • fastify: 4.0.3
  • path: 0.12.7
  • @fastify/view: 7.0.0
  • mongodb: 4.7.0
  • dotenv: 16.0.1
  • ejs: 3.1.8
  • @fastify/static: 6.4.0
  • @fastify/formbody: 7.0.1
  • fastify-plugin: 3.0.1
  • mongoose: 6.4.0

原有路由代码:

fastify.get("/result", async function (request, reply) {
 let search = request.query.search;
  
  if (search) {
    await dbAnime.find({ aliases: search })
      .toArray(async function (err, have) {
      if (!err) {
          if (have.length > 0) {
             reply.view("/pages/result.ejs", { results: have }).then(() => {
                console.log("replied")
             });
         console.log(have);
          client.close;    
          } else {
              reply.view("/pages/result.ejs", { results: have });
          }
        } else {
          reply.code(400)
          console.error(err);
        }
      });
  };
});

对应EJS模板代码:

<!DOCTYPE html>
<html data-theme="">
  <head>
    <link rel="stylesheet" href="css/style.css">
    <link rel="stylesheet" href="css/card.css">
    <link rel="preconnect" href="https://fonts.googleapis.com/">
    <link rel="preconnect" href="https://cdn.glitch.global/">
    <link rel="preconnect" href="https://cdn.discordapp.com/">
    <link rel="icon" type="image/png" href=""/>
    
    <title><%= results.length %> Résultat</title>
    </head>
  <body>
 
    <div class="form-container">
              <form class="form" action="/result">
                  <input id="myInput" type="text" class="input" name="search" placeholder="Rechercher un anime..."/>
      </form>
    </div>
    <h2>Résultat: <%= results.length %></h2>
    <% results.forEach(function(result){%>
<div class="paper" id="paper"><img class="poster" src="<%= result.image %>"/>
  
  <h1><%= result.title %></h1>
  <hr/>
  <p><%= result.synopsis %></p><a class="btn" href="/info?animeName=<%= result.title %>">En savoir plus</a>
  <div class="space"></div>
</div>
      <% }); %>
  </body>

</html>
故障根因

核心问题是异步写法混用违反Fastify 4的请求处理逻辑,具体问题点:

  1. MongoDB驱动的toArray方法如果传入回调函数,就不会返回Promise,前面加的await实际等待的是undefined,外层async路由函数会直接执行结束。Fastify 4对async路由的默认规则是:函数执行完如果没返回内容、也没触发reply.send(),就会直接结束请求,这时候toArray的回调还没执行,等回调里调用reply.view的时候请求已经关闭,所以页面返回空白,也不会抛出常规报错。
  2. 边界情况没处理:当search参数不存在时,路由函数没有任何返回逻辑,必然返回空白。
  3. 代码笔误:client.close是属性引用,不是方法调用,实际不会执行数据库连接关闭操作。
  4. 错误分支不完整:数据库查询报错时只设置了400状态码,没有返回任何响应内容。
  5. 逻辑错误:MongoClient是连接池实例,不应该在单次请求处理完就关闭,否则后续请求会出现数据库连接失败问题,应该在服务整体关闭时统一断开连接。
修复代码

将路由逻辑统一改成async/await写法,不要混用回调,修复后代码如下:

fastify.get("/result", async function (request, reply) {
  const search = request.query.search;
  // 处理无搜索参数的情况,避免返回空
  if (!search) {
    return reply.view("/pages/result.ejs", { results: [] });
  }

  try {
    const have = await dbAnime.find({ aliases: search }).toArray();
    console.log(have);
    // 异步路由直接return reply.view的结果即可,Fastify会自动处理响应发送
    return reply.view("/pages/result.ejs", { results: have });
  } catch (err) {
    console.error(err);
    return reply.code(400).send("数据库查询出错");
  }
});
额外检查项

如果改完代码还是有问题,确认@fastify/view的注册配置正确,参考配置如下:

const fastify = require('fastify')({ logger: true });
const path = require('path');

fastify.register(require('@fastify/view'), {
  engine: {
    ejs: require('ejs')
  },
  root: path.join(__dirname, '你的模板文件存放目录') // 替换为实际的模板目录绝对路径
});

注意:原代码里view路径写的是/pages/result.ejs,要确认这个路径和注册view时配置的root路径拼接后能正确找到模板文件,否则也会出现空白问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:15:43