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

Node.js区块链项目:Socket.io传输区块数组前端循环失效问题

区块链区块展示问题:Socket.io传输数组后前端无法遍历

我在Node.js中开发区块链项目,尝试将生成的区块在HTML页面中展示。使用Socket.io向HTML发送数据,但在传输区块链中的区块对象数组时遇到问题。

代码实现

服务端代码(Client.js)

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
const myArgs = process.argv.slice(2);
const port = myArgs[0];
const SHA256 = require("crypto-js/sha256");

class Block {
    constructor(index, timestamp, data, previousHash) {
        this.index = index;
        this.timestamp = timestamp;
        this.data = data;
        this.previousHash = previousHash;
        this.hash = this.generateHash();
    }
    generateHash() {
        return SHA256(this.index + this.timestamp + this.previousHash + JSON.stringify(this.data)).toString();
    }
}

class Blockchain {
    constructor() {
        this.blockchain = [this.createGenesisBlock()];
    }

    createGenesisBlock() {
        return new Block(0, Date.now(), "prvi blok verige", "0");
    }

    getTheLatestBlock() {
        return this.blockchain[this.blockchain.length - 1];
    }

    addNewBlock(newBlock) {
        newBlock.previousHash = this.getTheLatestBlock().hash;
        newBlock.hash = newBlock.generateHash();
        this.blockchain.push(newBlock);
    }

    validateBlock(newBlock) {
        const latestBlock = this.getTheLatestBlock();
        if (newBlock.previousHash !== latestBlock.hash)
            return false;
        if (newBlock.index <= latestBlock.index)
            return false;
        if (newBlock.hash !== newBlock.generateHash())
            return false;
        return true;
    }

    validateChain() {
        for (let i = 1; i < this.blockchain.length; i++) {
            const currentBlock = this.blockchain[i];
            const previousBlock = this.blockchain[i - 1];
            if (currentBlock.hash !== currentBlock.generateHash()) {
                return false;
            }
            if (currentBlock.previousHash !== previousBlock.hash) {
                return false;
            }
            if (currentBlock.index <= previousBlock.index)
                return false;
            return true;

        }
    }
}
app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
    console.log('GUI connected on port: ' + port);
    socket.emit('onConnection', port);

    let logCoin = new Blockchain();
    console.log("mining logcoin in progress...");
    logCoin.addNewBlock(
        new Block(1, Date.now(),"Block 1")
    );

    logCoin.addNewBlock(
        new Block(2, Date.now(), "Block 2")
    );

    logCoin.addNewBlock(
        new Block(3, Date.now(),"Block 3")
    );
    console.log(logCoin);
    socket.emit('blockLedger', JSON.stringify(logCoin,null));


    socket.on('disconnect', () => {
        console.log("Client has disconnected");
    });
});

server.listen(port, () => {
    console.log('listening on port ' + port + ':');
});

前端代码(index.html)

<!DOCTYPE html>
<html>

<style>
    body {
        margin: 10px;
        padding-bottom: 3rem;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    }

    #header {
        display: flex;
        flex-direction: row;
    }

    #contentWrap {
        display: flex;
        width: 100%;
        flex-direction: row;
        align-items: stretch;
        justify-content: space-between;
        margin-top: 10px;
    }

    #contentWrap>div {
        flex: 1;
        border: 1px solid black;
    }

    #blocks {
        list-style-type: none;
        margin: 0;
        padding: 0;
    }

    #blocks>li {
        padding: 0.5rem 1rem;
    }

    #blocks>li:nth-child(odd) {
        background: #efefef;
    }

    #minedBlocks {
        list-style-type: none;
        margin: 0;
        padding: 0;
    }

    #minedBlocks>li {
        padding: 0.5rem 1rem;
    }

    #minedBlocks>li:nth-child(odd) {
        background: #efefef;
    }

    #port {
        position: absolute;
        right: 10px;
    }
</style>

<body>
    <div id="header">
        <div id="element1">
            <h1>Blockchain</h1>
            <p id="connectionStatus">Status: Offline</p>
            <form id="form" action="">
                <button id="mine">Mine</button>
            </form>
        </div>
        <div id="element2" style="align-self: center;">
            <form id="form" action="">
                <div id="port">
                    <input id="portInput" autocomplete="off" /><button>Connect port</button>
                </div>
            </form>
        </div>
    </div>
    <div id="contentWrap">
        <div id="ledger">
            <ul id="blocks">
                <li>Blockchain ledger</li>
            </ul>
        </div>
        <div id="mined">
            <ul id="minedBlocks">
                <li>Mining...</li>
            </ul>
        </div>
    </div>

    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io();
        socket.on('onConnection', function (msg) {
            document.getElementById('connectionStatus').innerText = "Status: Online: PORT " + msg;
        });
        socket.on('blockLedger', function (msg) {
            var index;
            var data;
            var timeStamp;
            var previousHash;
            var hash;
            var blocks = document.getElementById('blocks');
            var obj = JSON.parse(msg);
            obj.forEach(function (arrayItem) {          // 这里尝试遍历数组,但无效果
                let item = document.createElement("li");
                item.textContent = arrayItem.index;
                blocks.appendChild(item);
                window.scrollTo(0, document.body.scrollHeight);
            })

        })

    </script>
</body>

</html>

问题现象

尝试将所有block的索引添加到页面列表中,但列表无任何内容,推测forEach循环未正常执行。

服务端的logCoin是Blockchain实例,其内部包含blockchain数组存储所有区块;序列化后前端接收到的是包含blockchain属性的对象,而非直接的区块数组。

编辑说明

已采用@ZackNewsham的解决方案,问题已解决,感谢!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:35:43