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

Node.js如何从数据库获取登录用户全部图片并渲染到EJS页面

问题根因

  • 重复调用res.render:HTTP响应是单次性的,res.render执行后就会把渲染好的页面和响应头一起返回给客户端,循环内多次调用就会触发Cannot set headers after they are sent to the client报错
  • 误用await:你在普通回调函数中使用await,但该回调没有被标记为async,此处await没有任何实际作用
  • 数据传递逻辑错误:每次仅传递单张图片信息给模板,且模板仅处理单张图片渲染,自然无法展示全部图片

修复后的服务端代码

app.get('/galery/galery', (req, res) => {
  conn.query("SELECT pic_name, user_id FROM galery WHERE user_id =?", [req.session.userId], function (err, result) {
    if (err || !result.length) {
      // 无数据或查询错误时传递空数组
      return res.render('./galery/galery', { imgs: [] })
    }
    // 先把所有图片路径拼好存入数组
    const imgs = result.map(item => {
      return {
        url: 'upload/' + item.pic_name,
        name: item.pic_name
      }
    })
    // 一次性把数组传给模板,仅调用一次render
    res.render('./galery/galery', { imgs: imgs })
  })
})

修复后的EJS模板代码

<div class="galery">
  <% imgs.forEach(img => { %>
    <div>
      <img src="<%= img.url %>"  alt="img" width="600" height="400">
      <div class="style"><%= img.name %>
        <form action="deleteImg.php" method="post">
          <input type="hidden" name="deleteImg" value="<%= img.name %>">
          <button class="btn btn-danger" name="delete" type="submit" >delete</button>
        </form>
      </div>
    </div>
  <% }) %>
</div>

async/await适用说明

如果你的数据库连接库支持Promise风格调用,才需要用async/await简化异步代码,当前你用的是回调风格的查询逻辑,不需要额外使用async/await。如果要切换为Promise风格写法,可以参考如下结构:

app.get('/galery/galery', async (req, res) => {
  try {
    const result = await conn.query("SELECT pic_name, user_id FROM galery WHERE user_id =?", [req.session.userId])
    const imgs = result.map(item => ({ url: 'upload/' + item.pic_name, name: item.pic_name }))
    res.render('./galery/galery', { imgs })
  } catch (err) {
    res.render('./galery/galery', { imgs: [] })
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 12:15:03