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

循环遍历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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:05:56