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

使用AXIOS、EJS、Node.js和Express.js渲染API JSON时遇Undefined错误

解决TheCocktailDB API数据渲染时的Undefined错误

问题描述

尝试从公共API获取随机饮品名称,但渲染JSON数据时一直出现"Undefined"错误,无法展示数据。使用Axios请求API后,尝试用JSON.parse()转换数据再传给EJS模板,在模板中通过forEach()遍历数组属性渲染内容。

核心错误与修复方案

1. 错误解析Axios响应数据

Axios会自动将JSON格式的响应体解析为JavaScript对象,无需额外调用JSON.parse()。强行解析已转换的对象会抛出错误,导致drink变量无法正确传递给模板,最终触发Undefined报错。

修复后的index.js POST请求代码:

app.post("/", async (req, res) => {
    try {
        const response = await axios.get(API_URL);
        // 直接使用Axios已解析好的response.data
        res.render("index.ejs", {
            drink: response.data,
        });
     } catch (error) {
        console.error(error); // 正确打印错误信息
        res.status(500).send("获取饮品数据失败"); // 返回明确的错误响应
     } 
});

2. EJS模板HTML结构错误

原模板中<div class="cocktail-box"></div>提前闭合,导致列表项被渲染在div外部;同时列表项缺少<ul>/<ol>容器,不符合HTML语义规范。

修复后的EJS渲染部分代码:

<% if (locals.drink) { %>
  <div class="cocktail-box">
    <ul>
      <% drink.drinks.forEach(drinkDetail => { %>
       <li><%= drinkDetail.strDrink %></li> 
      <% }) %>
    </ul>
  </div>
<% } %>

3. 前端点击事件未生效

原JS代码定义了handleClick函数但未调用,导致点击按钮时的日志无法输出。可直接简化事件绑定逻辑:

修复后的前端脚本:

document.getElementById("buttonClick").addEventListener("click", () => {
    console.log("按钮已点击");
});

4. 初始页面渲染优化(可选)

初始访问页面时,可默认获取一次随机饮品提升用户体验:

app.get("/", async (req, res) => {
    try {
        const response = await axios.get(API_URL);
        res.render("index.ejs", { drink: response.data });
    } catch (error) {
        console.error(error);
        res.render("index.ejs"); // 失败时渲染空页面
    }
});

完整修改后代码

index.js

import express from "express";
import bodyParser from "body-parser";
import axios from "axios";

const app = express();
const port = 3000;
const API_URL = "https://www.thecocktaildb.com/api/json/v1/1/random.php";

app.use(express.static("public"));
app.use(bodyParser.urlencoded({ extended: true }));

app.get("/", async (req, res) => {
    try {
        const response = await axios.get(API_URL);
        res.render("index.ejs", { drink: response.data });
    } catch (error) {
        console.error(error);
        res.render("index.ejs");
    }
});

app.post("/", async (req, res) => {
    try {
        const response = await axios.get(API_URL);
        res.render("index.ejs", {
            drink: response.data,
        });
     } catch (error) {
        console.error(error);
        res.status(500).send("获取饮品数据失败");
     } 
});

app.listen(port, () =>{
    console.log(`Server is running on ${port}`);
});

index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cocktails Generator</title>
</head>
<body>
    <h1>Cocktails</h1>
    <br />

<form action="/" method="POST">
<button type="submit" name="buttonDrink" id="buttonClick">GET A DRINK</button>
</form>

<p>Your drink:</p>
<% if (locals.drink) { %>
  <div class="cocktail-box">
    <ul>
      <% drink.drinks.forEach(drinkDetail => { %>
       <li><%= drinkDetail.strDrink %></li> 
      <% }) %>
    </ul>
  </div>
<% } %>

<script>
document.getElementById("buttonClick").addEventListener("click", () => {
    console.log("按钮已点击");
});
</script>
</body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:38:12