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

axios GET请求获取API数据EJS渲染时报ERR_HTTP_HEADERS_SENT错误

报错根因

Error [ERR_HTTP_HEADERS_SENT] 是因为同一次请求触发了两次响应:

  • 第一次是axios请求成功回调里的res.json(response.data),已经把接口数据作为响应发回给客户端,响应头已经发送完成
  • 紧接着同步执行的res.render('produtos2', {product: productApi}) 尝试第二次发送响应,自然会触发报错。

你调整后的第二版代码只保留了res.json()逻辑,根本没有执行EJS渲染,自然能返回接口数据但出不来视图。另外初始写法还有个问题:axios.get()返回的是Promise对象,你没等异步请求resolve拿到实际数据就执行渲染,传给EJS模板的根本不是接口返回的真实数据。

正确实现代码

推荐用async/await写法,逻辑更清晰,记得加错误捕获:

app.get("/test", async (req, res, next) => {
  try {
    // 等待接口请求完成,拿到真实返回数据
    const apiRes = await axios.get("https://swapi.dev/api/people/1")
    const productData = apiRes.data
    // 拿到数据后再执行视图渲染,整个请求只发这一次响应
    res.render('produtos2', {product: productData})
  } catch (err) {
    next(err)
  }
})

如果习惯Promise链式写法,用下面的版本也可以:

app.get("/test", (req, res, next) => {
  axios.get("https://swapi.dev/api/people/1")
    .then(response => {
      // 注意不要在这里写res.json,拿到数据后直接渲染
      res.render('produtos2', {product: response.data})
    })
    .catch(err => next(err))
})
EJS模板调整

你调用的接口返回的是单个对象结构,不是数组,所以原来模板里的<%= product[0] %>写法不对,按对象属性取值即可,比如要展示人物名称就写<%= product.name %>,调整后模板:

<%- include('partials/header') %>

teste view

<%= product.name %>

<%- include('partials/footer') %>
关键注意点
  • 单次HTTP请求只能返回一次响应,要渲染EJS就不要同时写res.json(),二者只能选一个
  • 异步接口请求必须等待结果返回后,再把真实数据传给res.render(),不能直接把Promise对象作为模板数据传入
  • 渲染前先确认接口返回的数据结构,对象按属性取值、数组按下标取值,避免模板渲染报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:48:15