循环遍历JS对象时出现"Invalid string length"错误求助
问题描述
我是编程新手,正在开发首个每日费用追踪应用。需求是用户添加物品(如咖啡)和金额时,生成包含该物品与金额的新div,每次添加都需生成新div。尝试用for循环实现时出现**"Invalid string length"**错误,使用Node.js、Express和EJS技术栈,附上相关代码片段,求修复方案或替代实现方式。
EJS代码片段
<div class = "add-new-item"> <div class = "add-item"> <form class= "item" action = "/add-new-item" method="post"> <input type="text" name="newItem" placeholder="Item" autocomplete="off" autofocus="true" /> <input type="text" name="newAmount" placeholder="Amount" autocomplete="off" autofocus="true" /> <button type="submit" value="Add" id="addBtn">+</button> </form> </div> </div> <%if (locals.item && locals.amount) {%> <%let items = [];%> <%items.push({item, amount});%> <%console.log(items);%> <%for(let i = 0; i = Object.keys(items).length; i++) {%> <div class = "new-item"> <div class = "item"> <%= item %> </div> <div class = "amount"> €<%= amount %> </div> </div><% %> <%}%> <% };%>
JS代码片段
import express from "express"; import bodyParser from "body-parser"; const app = express(); const port = 3000; app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static("public")); app.get("/", (req, res) => { res.render("index.ejs"); }); app.post("/add-new-item", async (req, res) => { const item = req.body.newItem; const amount = req.body.newAmount; res.render("index.ejs", {item: item, amount: amount}); }); app.listen(port, () => { console.log(`API is running at http://localhost:${port}`); });
修复方案与优化实现
1. 解决无限循环导致的错误
你的EJS循环条件使用了赋值运算符=而非比较运算符,导致循环无限执行,最终抛出"Invalid string length"错误:
// 错误写法 <%for(let i = 0; i = Object.keys(items).length; i++) {%>
替换为正确的比较逻辑,且数组直接用.length属性即可,无需Object.keys:
// 正确写法 <%for(let i = 0; i < items.length; i++) {%>
2. 实现历史条目持久化
当前代码每次提交仅传递单个条目,且EJS每次重新创建空数组,无法保留历史记录。需在服务器端维护全局数组存储所有条目:
修改服务器JS代码:
import express from "express"; import bodyParser from "body-parser"; const app = express(); const port = 3000; // 全局数组存储所有费用条目 const expenseItems = []; app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static("public")); app.get("/", (req, res) => { // 渲染时传递全部条目 res.render("index.ejs", { expenses: expenseItems }); }); app.post("/add-new-item", async (req, res) => { const item = req.body.newItem; const amount = req.body.newAmount; // 添加新条目到全局数组 expenseItems.push({ item, amount }); // 重定向避免表单重复提交 res.redirect("/"); }); app.listen(port, () => { console.log(`API is running at http://localhost:${port}`); });
3. 优化EJS渲染逻辑
修改EJS,直接遍历服务器传递的expenses数组,用forEach替代for循环更简洁:
<div class = "add-new-item"> <div class = "add-item"> <form class= "item" action = "/add-new-item" method="post"> <input type="text" name="newItem" placeholder="Item" autocomplete="off" autofocus="true" /> <!-- 改为number类型限制输入 --> <input type="number" name="newAmount" placeholder="Amount" autocomplete="off" step="0.01" /> <button type="submit" value="Add" id="addBtn">+</button> </form> </div> </div> <% if (locals.expenses && expenses.length > 0) { %> <% expenses.forEach(expense => { %> <div class = "new-item"> <div class = "item"> <%= expense.item %> </div> <div class = "amount"> €<%= expense.amount %> </div> </div> <% }) %> <% } %>
额外优化建议
- 给金额输入框设置
type="number"并添加step="0.01",限制用户只能输入合法金额 - 服务器端可添加简单验证,确保item和amount不为空再添加到数组
内容的提问来源于stack exchange,提问作者Iana Barkhatova
相关产品推荐
相关产品推荐

