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

Node-RED自定义节点RED.httpAdmin.get返回旧数据求助

问题根源

重新部署后HTTP端点返回旧数据/空数组的核心原因:

  • Node-RED部署时不会自动清理旧节点已注册的HTTP路由,旧节点触发close事件清空items后,请求仍可能命中旧节点的端点,返回空数组;若不清空items,旧节点端点会返回残留的旧数据。
  • 原代码中items是闭包变量,端点函数捕获的是旧节点的变量引用,无法获取新节点的最新数据。
  • 浏览器对GET请求的默认缓存,会导致重复请求返回旧结果。
解决方案

1. 将items改为节点实例属性

把items挂载到node对象上,确保每个节点实例拥有独立的数据源,避免跨实例数据污染。

2. 节点关闭时卸载HTTP端点

在close事件中移除已注册的路由,彻底清理旧节点的影响。

3. 禁用浏览器GET请求缓存

在HTML请求中添加时间戳参数,强制浏览器每次获取最新数据。

修改后的代码片段

JS节点代码

// 将items改为节点实例属性,每个节点独立维护
node.items = [];

// HTTP端点直接返回当前节点的items数据
RED.httpAdmin.get("/plc-options" + node.id, function (req, res) {
    res.json(node.items);
});

async function setupClient(url) {
    const client = opcua.OPCUAClient.create(connectionOption);
    try {
        await client.connect(url);
        const session = await client.createSession(userIdentity);
        var crawler = new NodeCrawler(session);
        node.status({
            fill: "blue",
            shape: "dot",
            text: "Browsing variables in the server."
        });
        const tempItems = [];
        crawler.on("browsed", function (element) {
            if (element.nodeClass === 2 && element.accessLevel === 3) {
                tempItems.push(element);
            }
        });
        await crawler.read(node.topic);
        // 更新当前节点实例的items
        node.items = [...tempItems];
        node.status({
            fill: "green",
            shape: "dot",
            text: "Successfully found all variables."
        });
        client.disconnect();
    } catch (err) {
        node.status({
            fill: "red",
            shape: "dot",
            text: err.toString()
        });
    }
}

node.on("input", function (msg) {
    if (this.plcName === '') {
        node.status({
            fill: "red",
            shape: "dot",
            text: "Please fill plc name area."
        });
    }
    setupClient(opcuaEndpoint.endpoint);
});

node.on("close", function () {
    // 清空当前节点的items
    node.items = [];
    // 卸载当前节点的HTTP端点,避免旧路由干扰
    RED.httpAdmin.unmount("/plc-options" + node.id);
});

HTML编辑页代码

const fetch = setInterval(() => {
    // 添加时间戳参数,强制浏览器不缓存请求结果
    $.getJSON("plc-options" + this.id + "?t=" + Date.now(), function (data) {
        if (data.length > 0) {
            $("#node-input-plc-options").empty(); // 先清空旧选项,避免重复渲染
            for (var i = 0; i < data.length; i++) {
                generateOption(data[i]);
            }
            $("#loading").empty().remove();
            clearInterval(fetch);
        }
    });
}, 1000);

注:原HTML代码中$("#node-input-plc-options").append(${data})会直接将数组转为字符串追加,导致页面显示异常,此处改为先清空容器再逐个生成选项。

验证逻辑
  • 重新部署时,旧节点触发close事件,清空自身数据并卸载端点,彻底清理旧实例的影响。
  • 新节点初始化时重新注册端点,setupClient更新的是自身实例的items属性,确保端点返回最新数据。
  • 请求添加时间戳后,浏览器不会缓存旧响应,保证每次请求都获取最新结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:46:04