使用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
相关产品推荐
相关产品推荐

