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

Express+EJS页面渲染后重复请求触发空值读取错误

问题描述

我有一个Express路由/vote/:id,逻辑是先从数据库查询数据,再渲染vote.ejs页面展示数据。页面能正常显示数据,但之后会额外发起2次请求,导致同一个TypeError错误重复出现两次,错误信息为“Cannot read properties of null (reading 'id')”。

相关代码

路由代码

app.get("/vote/:id", checkAuth, async (req, res) => {  
    let botVote = await botDoc.findOne({ id: req.params.id });
    renderWeb("vote.ejs", req, res, { bot: botVote });
});

EJS页面代码

<html lang="en">
    <%- include('partials/head') %>  
<body>
    
    <%- include('partials/navbar') %> <br>
    
    <div class="container" style="padding-top: 69px; margin-left: 40%;">

    <div class="vote">
        <%= bot.id %> 
    </div>
        
    </div>
        
    </div>
<br><%- include('partials/footer') %> 


<script>

</script>
</body>
</html>

报错信息

TypeError: D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\views\vote.ejs:10
8|
9|     
10|         <%= bot.id %>
11|     
12|
13|     
Cannot read properties of null (reading 'id')
at eval ("D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\views\vote.ejs":18:30)
at vote (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\ejs\lib\ejs.js:692:17)
at tryHandleCache (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\ejs\lib\ejs.js:272:36)
at View.exports.renderFile [as engine] (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\ejs\lib\ejs.js:489:10)
at View.render (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\view.js:135:8)
at tryRender (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\application.js:640:10)
at Function.render (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\application.js:592:3)
at ServerResponse.render (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\response.js:1012:7)
at renderWeb (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\main.js:32:9)
at processTicksAndRejections (node:internal/process/task_queues:96:5)

TypeError: D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\views\vote.ejs:10
8|
9|     
10|         <%= bot.id %>
11|     
12|
13|     
Cannot read properties of null (reading 'id')
at eval ("D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\views\vote.ejs":18:30)
at vote (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\ejs\lib\ejs.js:692:17)
at tryHandleCache (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\ejs\lib\ejs.js:272:36)
at View.exports.renderFile [as engine] (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\ejs\lib\ejs.js:489:10)
at View.render (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\view.js:135:8)
at tryRender (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\application.js:640:10)
at Function.render (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\application.js:592:3)
at ServerResponse.render (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\node_modules\express\lib\response.js:1012:7)
at renderWeb (D:\Users\ahmed\Documents\Coding\Projects\Beats'List2\main.js:32:9)
at processTicksAndRejections (node:internal/process/task_queues:96:5)

解决方案

1. 定位额外请求来源

页面正常显示后出现的重复请求,大概率是浏览器自动发起的,比如:

  • 浏览器默认请求favicon.ico(若项目未配置该文件,请求会落到/vote/:id路由,此时req.params.id为favicon.ico,数据库查不到数据,botVote为null,渲染时触发错误)
  • 页面内引用的CSS、JS或图片路径错误,导致请求匹配到/vote/:id路由

可以在路由中添加日志,打印请求参数和URL,确认请求详情:

app.get("/vote/:id", checkAuth, async (req, res) => {  
    console.log(`请求ID: ${req.params.id}, 请求URL: ${req.url}`);
    let botVote = await botDoc.findOne({ id: req.params.id });
    renderWeb("vote.ejs", req, res, { bot: botVote });
});

2. 处理查询结果为空的情况

无论请求来源如何,都要避免渲染时访问null对象的属性,有两种处理方式:

  • 后端拦截:在路由中判断查询结果,为空则返回404或错误页面:
app.get("/vote/:id", checkAuth, async (req, res) => {  
    let botVote = await botDoc.findOne({ id: req.params.id });
    if (!botVote) {
        return res.status(404).send("数据不存在");
        // 或渲染404页面:return res.render("404.ejs");
    }
    renderWeb("vote.ejs", req, res, { bot: botVote });
});
  • 前端防御:在EJS模板中添加判断,避免直接访问bot.id:
<div class="vote">
    <%= bot ? bot.id : "数据不存在" %> 
</div>

3. 解决favicon请求问题

如果是favicon导致的问题,可通过以下方式处理:

  • 在项目根目录放置favicon.ico文件
  • 专门配置路由处理favicon请求:
app.get('/favicon.ico', (req, res) => res.status(204).end());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:12:55