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

Express+WebSocket实现实时商品表格 点击发送无响应问题求助

WebSocket实时商品列表故障修复

核心故障原因

  • 发送按钮位于<form>标签内,未指定type="button"时默认行为是触发表单提交刷新页面,点击后socket.emit逻辑还未执行页面就已重载,服务端无法接收到商品上报消息,仅能打印初始连接日志。
  • 原有逻辑存在三个体验缺陷:一是每次接收商品都生成带重复表头的独立表格,页面结构冗余;二是服务端未存储历史商品,新接入用户无法看到之前提交的商品记录;三是缩略图仅输出文本URL,未渲染为图片,不符合功能预期。

分步修复代码

1. HTML部分调整

给按钮添加type="button"阻断默认表单提交,提前固定表格结构,补全Bootstrap基础样式类:

<div class="container mt-3 bg-dark">
    <h1 class="text-center text-primary">Ingrese datos</h1>

    <form class="text-light">
        <div class="form-group">
            <label for="title"><b>Producto</b></label>
            <input id="title" type="text" name="title" class="form-control">
        </div>
    
        <div class="form-group">
            <label for="price"><b>Precio</b></label>
            <input id="price" type="number" name="price" class="form-control">
        </div>
    
        <div class="form-group">
            <label for="thumbnail"><b>Thumbnail</b></label>
            <input id="thumbnail" type="text" name="thumbnail" class="form-control">
        </div>
    
        <button id="send" type="button" class="btn btn-primary mt-2">Postear</button>
    </form>

    <h2 class="text-center text-danger mt-4">Historial</h2>

    <div id="output">
        <table class="table table-dark">
            <thead>
                <tr class="text-warning">
                    <th>Title</th>
                    <th>Price</th>
                    <th>Thumbnail</th>
                </tr>
            </thead>
            <tbody id="product-list"></tbody>
        </table>
    </div>
</div>

2. 前端JS逻辑调整

在点击事件中增加默认行为阻断兜底,渲染时仅向表格主体追加商品行,增加新连接时的历史商品拉取逻辑,补全缩略图渲染、空值校验、提交后清空输入框的基础交互:

const socket = io();

const titleInput = document.getElementById("title")
const priceInput = document.getElementById("price")
const thumbnailInput = document.getElementById("thumbnail")
const sendBtn = document.getElementById("send")
const productContainer = document.getElementById("product-list")


sendBtn.addEventListener("click", function(e){
    e.preventDefault();
    const title = titleInput.value.trim();
    const price = priceInput.value.trim();
    const thumbnail = thumbnailInput.value.trim();

    if(!title || !price || !thumbnail){
        alert('请填写完整商品信息');
        return;
    }

    socket.emit("products", {title, price, thumbnail});
    
    titleInput.value = '';
    priceInput.value = '';
    thumbnailInput.value = '';
});

// 监听实时新增商品
socket.on("products", function (data) {
    const row = document.createElement('tr');
    row.innerHTML = `
        <td>${data.title}</td>
        <td>$${data.price}</td>
        <td><img src="${data.thumbnail}" style="max-width: 80px; max-height: 80px; object-fit: cover;" alt="${data.title}"></td>
    `;
    productContainer.appendChild(row);
})

// 监听连接初始化时的历史商品列表
socket.on("init-product-list", function (list) {
    list.forEach(data => {
        const row = document.createElement('tr');
        row.innerHTML = `
            <td>${data.title}</td>
            <td>$${data.price}</td>
            <td><img src="${data.thumbnail}" style="max-width: 80px; max-height: 80px; object-fit: cover;" alt="${data.title}"></td>
        `;
        productContainer.appendChild(row);
    });
})

3. 服务端JS逻辑调整

增加历史商品存储数组,新用户连接时主动推送全量历史商品,收到新商品时先入存储再广播给所有连接用户:

const path = require("path")
const express = require("express")
const app = express()

app.set("port", process.env.PORT || 8080)
app.use(express.static(path.join(__dirname, "public")))

const server = app.listen(app.get("port"), ()=>{
    console.log("server on port", app.get("port"))
})

const SocketIO = require("socket.io")
const io = SocketIO(server)

// 存储全量商品历史
const productStore = [];

io.on("connection", (socket)=>{
    console.log("new connection", socket.id)
    // 新连接建立后推送历史商品
    socket.emit("init-product-list", productStore);

    socket.on("products", (data) => {
        productStore.push(data);
        // 广播新商品到所有客户端
        io.emit("products", data);
    })
})

注意:确认你的HTML页面中已经正确引入了Socket.IO客户端脚本,否则io()会直接报错,脚本引入地址默认和服务端同域时为<script src="/socket.io/socket.io.js"></script>,需要放在你自己编写的前端JS之前引入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 20:31:03