【问题标题】:node.js express res.send in callback issuenode.js 在回调问题中表达 res.send
【发布时间】:2016-12-12 09:44:36
【问题描述】:

我有一个 node.js 脚本,其中包含两件事:

  1. 启动一个 http 服务器,监听来自浏览器的 POST 请求。
  2. 启动套接字连接到 java 服务器

当来自浏览器的请求时,我会使用套接字将一些数据发送到 java 服务器,然后将数据从 java 服务器以 http 响应返回给浏览器。

第一个请求可以正常工作,但在第二个请求中我会收到错误:

Error: Can't set headers after they are sent.

这里是 node.js 脚本:

var client = new net.Socket();
var clientConnected = false;

app.options('*', cors());

app.use(function(req, res, next) {
    var data = new Buffer('');
    req.on('data', function(chunk) {
        // read buffer data from the browser in the POST request
        data = Buffer.concat([data, chunk]);
    });
    req.on('end', function() {
        req.rawBody = data;
        next();
    });
});

app.post('/xxxxxx', function(req, res) {
    res.header("Access-Control-Allow-Origin", "*");

    if (!clientConnected) {
        // if the socket is not connected, create it
        client.connect(G_PORT, G_ADDRESS, function() {
            clientConnected = true;
        });

        client.on('close', function() {
            clientConnected = false;
        });

        client.on('data',function(data) {
            // get result from the java server through socket
            res.send(data);
        });

        client.on('error', function(error){
            clientConnected = false;
        });
        res.send();
    }
    else {
        // the socket is created, just send the data to socket
        client.write(req.rawBody);
    }
}); 

错误指向了这一行:

res.send(data);

client.on('data',function(data)

我对表达很陌生,希望有人能给我一些建议,谢谢:)

更新:

我尝试在每次完成一个请求时关闭套接字,在这种情况下一切正常:

if (true) {
    var client = new net.Socket();
    client.connect(G_PORT, G_ADDRESS, function() {
        client.write(data);
    });
    client.on('close', function(){
    });

    client.on('data',function(data){
        res.send(decodeData);
        client.destroy();
    });

    client.on('error', function(error){
    });
}

似乎问题与我的全局套接字实例有关???

【问题讨论】:

    标签: javascript node.js sockets express


    【解决方案1】:

    错误“错误:发送后无法设置标头。”当你调用 res.send 时来。

    根据您的发布请求,您有 2 res.send

        client.on('data',function(data) {
            // get result from the java server through socket
            res.send(data);
        });
    
        client.on('error', function(error){
            clientConnected = false;
        });
        res.send();
    

    当客户端使用“数据”时,您还会在 res.send 中发送,这会出错。每个请求只需要一个 res.send

    【讨论】:

    • 感谢您的快速回复。我试图注释掉第二个 .send 函数,但我仍然遇到同样的错误。
    • 顺便说一句,第二个 .send 函数只会在第一次发布请求时触发。在第一个请求中,我不会向服务器发送任何数据(仅创建套接字),因此不会触发回调中的 .send 函数。
    • 这很正常。当您的客户端在“数据”上时,您 res.send,并且数据最大值的默认大小为 8192。因此,如果您有 10000 条消息,您将在 client.on('data', -> 上两次,您将调用两次重新发送
    • 您希望通过发布请求实现什么?
    • 我想使用socket将数据从浏览器发送到服务器,然后等待服务器的结果,最后将结果发送回服务器。
    【解决方案2】:

    也许你应该试试。

    var client = new net.Socket();
    var clientConnected = false;
    
    app.options('*', cors());
    
    app.use(function(req, res, next) {
        var data = new Buffer('');
        req.on('data', function(chunk) {
            // read buffer data from the browser in the POST request
            data = Buffer.concat([data, chunk]);
        });
        req.on('end', function() {
            req.rawBody = data;
            next();
        });
    });
    
    app.post('/xxxxxx', function(req, res) {
        res.header("Access-Control-Allow-Origin", "*");
    
        if (!clientConnected) {
            // if the socket is not connected, create it
            var buffer = '';
            client.connect(G_PORT, G_ADDRESS, function() {
                clientConnected = true;
            });
    
            client.on('close', function() {
                clientConnected = false;
            });
    
            client.on('data',function(data) {
                buffer += data;
            });
    
            client.on('error', function(error){
                clientConnected = false;
            });
            client.on('end', function() {
                res.send(buffer);
            });
        } else {
            // the socket is created, just send the data to socket
            client.write(req.rawBody);
            res.send(req.rawBody);
        }
    }); 
    

    【讨论】:

    • 我尝试了这个解决方案,这次错误消失了......但是“结束”回调从未触发,所以我的浏览器无法取回任何数据......
    • 试听密切的听众并告诉我;)
    • 你的意思是尝试添加 res.send(buffer);在关闭回调?我试过了,但是关闭回调永远不会触发,因为我的套接字在连接到服务器后会保持活动......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 2016-01-29
    • 1970-01-01
    • 2023-03-25
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多