Node.js Http 结束后写入

Posted

技术标签:

【中文标题】Node.js Http 结束后写入【英文标题】:Node.js Http Write after end 【发布时间】:2019-12-17 07:29:26 【问题描述】:

我在 node.js 中编写了一个简单的 CRUD Api。在我所有的 POST、PUT 和 DELETE 函数结束后,我一直在写。我已经失去了试图解决这个问题的所有感觉,并希望有一双新的眼睛或一些关于试图追踪它的建议。 GET 工作得非常好,并且在 httpmgs.js 中使用相同的代码 sendJSON()。

我分散了各种各样的 cmets,试图找出错误发生在哪里。我不知道 req.on("end".... 是否引起了问题,所以我重写了那部分无济于事。

controller.js:

 switch (req.method)
    case "GET":
          if(req.url === "/staff")
            staff.getList(req, resp);
        
        break;
    case "POST":
      if (req.url === "/staff/add")
            var reqBody = '';
            req.on("data", function (data)
                reqBody += data;
                if(reqBody.length > 1e7)
                    msg.show413(req, resp);              
                
            );
            req.on("end", function() 
                console.log(req.data)
                staff.add(req, resp, reqBody)
            );            
        
        break;
    case "PUT":
        if (req.url === "/staff/update")
            var reqBody = '';
            req.on("data", function (data)
                reqBody += data;
                if(reqBody.length > 1e7)
                    msg.show413(req, resp);
                
            );
            req.on("end", function() 
                staff.update(req, resp, reqBody);
            );

        
        else
            msg.show404(req,resp);
        
        break;

staff.js:

exports.add = function (req, resp, reqBody)
    try
        if (!reqBody) throw new Error("Input not valid");
        var data = JSON.parse(reqBody);
        if (data)

            db.executeSql("SELECT MAX(ID) AS ID FROM jarvisdb.staff",function (maxID, err)
                if(err)
                    msg.show500(req, resp, err);
                
                else
                    var newID = maxID[0].ID+1
                    var sql = "INSERT INTO jarvisdb.staff (`ID`, `First Name`, `Last Name`) VALUES";
                    sql+= util.format("('%d' ,\"%s\", \"%s\")", newID, data.firstName, data.lastName); 
                    db.executeSql(sql, (data, err)=>
                        if(err)
                            msg.show500(req, resp, err)
                        
                        else
                            console.log('Before send')
                            msg.sendJSON(req,resp,data)
                            console.log('After send')
                        
                    )

                
            );
        
        else
            throw new Error("Input not valid");
        
    
    catch (ex) 
        console.log('500')
        msg.show500(req, resp, ex);

    
;

httpMsgs.js:

exports.sendJSON = function(req,resp,data)
    if(data)
        console.log('Before Write')
        resp.writeHead(200, "Content-type" : "application/json");
        console.log('Write Head')
        resp.write(JSON.stringify(data));
        console.log('Write body')
        resp.end();
        console.log('end');
    

预期结果: 没有错误并返回 JSON

实际结果:

Listening on port 9000....
undefined
Before send
Before Write
Write Head
Write body
end
After send
events.js:174

      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at write_ (_http_outgoing.js:572:17)
    at ServerResponse.write (_http_outgoing.js:567:10)
    at Object.exports.sendJSON (E:\JARVIS\API\peak-2.0\httpMsgs.js:60:14)
    at db.executeSql (E:\JARVIS\API\peak-2.0\controllers\staff.js:53:33)
    at Execute.conn.execute [as onResult] (E:\JARVIS\API\peak-2.0\db.js:35:9)
    at process.nextTick (E:\JARVIS\API\peak-2.0\node_modules\mysql2\lib\commands\query.js:76:16)
    at process._tickCallback (internal/process/next_tick.js:61:11)
Emitted 'error' event at:
    at writeAfterEndNT (_http_outgoing.js:634:7)
    at process._tickCallback (internal/process/next_tick.js:63:19)

【问题讨论】:

【参考方案1】:

没有 break; 在您的case 之后。所以,当前匹配的case之外的所有case都会依次执行直到结束。

编辑

尝试重新启动您的 SQL 服务器

更新

您有两个选择: 在您的 sendJSON 函数中使用:

选项 1(无快递):

resp.writeHead('Content-Type', 'application/json'); resp.end(JSON.stringify(data));

选项 2(使用快递): 这里不需要指定header类型

res.json(data);

【讨论】:

抱歉,实际代码中存在中断。这只是一个sn-p。我将编辑问题 能否添加文件名以便更好地理解错误信息? 我写的错误中唯一缺少的代码是 db.js,它只是进行 mysql 数据库调用。 重启没有帮助。 你看过这个吗? ***.com/questions/19357539/…

以上是关于Node.js Http 结束后写入的主要内容,如果未能解决你的问题,请参考以下文章

学习使用node.js

学习使用node.js

Node 读取 + 写入 + 路径问题

在 Node.js 中如何停止脚本执行,成功向控制台写入错误消息,然后退出脚本?

在 Node.js HTTP 服务器上重用 TCP 连接

Node.js之HTTP请求与响应