json - NodeJS,如何在 GET 请求时调试 TLSSocket.socketOnData 的解析错误?

标签 json node.js debugging https get

我是 NodeJS 的新手,一直在 AWS Lambda 上尝试编写一个简单的 Alexa 服务来告诉我家里的温度。我遇到了一个让我卡住的问题 - 当我尝试与 https 端点通信以查询家庭自动化恒温器的一些数据时 - 我的 Node 应用程序因错误而终止:

Error: Parse Error
    at TLSSocket.socketOnData (_http_client.js:362:20)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at TLSSocket.Readable.push (_stream_readable.js:134:10)
    at TLSWrap.onread (net.js:551:20)

这是一个相当简单的通过 https 的 GET 请求,端点的提供者使用 Python 没有问题。我尝试将我的代码移动到笔记本电脑上的本地 Node 设置,但问题仍然存在(所以它不是 AWS)。因为它是 https 和我控制之外的服务,如果响应以某种微妙的方式损坏,我不能轻易地通过 wireshark 来发现流量 - 但是我尝试使用 Browsify 将代码转换为在网络浏览器中运行(我可以在其中使用wireshark),然后它当然可以工作,我看不出我得到的 json 响应有什么奇怪的。

我已经尝试使用响应模块而不是 Node 中的核心 https 库,但我仍然遇到相同的潜在错误。

我不知道我能做什么 - 不知道如何调试它。这让我觉得是格式问题或时间问题 - 但我不确定如何解决这个问题。有人有想法吗?

我的代码是这样的:

var https = require('https');
var crypto = require('crypto');

function executeHttpRequest(path, data, method, username, password) {

    var encodedLogin = getLoginString(username,password);
    var stringData = JSON.stringify(data);

    var requestOptions = {
        host: 'hub-server.domain.co.uk',
        port: 443,
        path: path,
        method: 'GET',
        headers: {
            'Cache-Control': 'no-cache',
            'Accept': 'application/json, text/plain, */*',
            'Authorization': 'Basic ' + encodedLogin
        }};

    var request = https.request(requestOptions, function(response) {

        var body='';
        response.setEncoding('utf8');

        response.on('error', function(err){
            console.log(method + " error: \n", err.stack);
        }); 

        response.on('data', function (chunk) {
            console.log("read data: " + chunk);
            body += chunk 
        });

        response.on('end', function () {
            console.log("end data");
        });

    });

    request.on('error', function(err) {
        console.log('request error: \n' + err.stack);
    });

    console.log("sending request:" + JSON.stringify(requestOptions));
    console.log("with data: " + stringData)

    request.write(stringData);  
    request.end();
    console.log("closed request")
}

在 Node 中运行时,我得到以下输出

sending request:{"host":"hub-server.domain.co.uk","port":443,"path":"/zone/1","method":"GET","headers":{"Cache-Control":"no-cache","Accept":"application/json, text/plain, */*","Authorization":"Basic bWFjdGEyOmY0OWZiODJlYTcyNWYzNDgwMTViODVjZTNlZmIyYmY1MWE4ZmI3YWUxMzJmZTRkNDk4OGEc"}}
closed request
request error: 
Error: Parse Error
    at TLSSocket.socketOnData (_http_client.js:362:20)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at TLSSocket.Readable.push (_stream_readable.js:134:10)
    at TLSWrap.onread (net.js:551:20)

我用类似的 PUT 命令得到了同样的错误。有趣的是,如果我在使用 PUT 时遗漏了一个参数,并且服务器回复了一个 JSON 错误,上面的代码可以工作并向我显示记录错误的 JSON。同样,如果我使用无效的 URL 或错误的 AUTH,我会正确地获得适当的状态代码。

如果我尝试点击 https://www.google.com,我的代码似乎也能正常工作并进行搜索。

显然有些事情发生了 - 但我如何才能更正我的 Node 代码,或者建议端点的作者?

最佳答案

响应同时包含Content-LengthTransfer-encoding: chunked header (这是一个错误)

使用调试器我发现 http 解析器实际上显示错误代码:HPE_UNEXPECTED_CONTENT_LENGTH - 在谷歌上搜索更多关于这个的信息,我看到其他几个人也经历过这个(有趣的是,所有与家庭自动化有关) - 和结论这些线程是由于安全问题,更高版本的 Node 对 HTTP 规范变得更加严格。有了这个错误代码,搜索揭示了两个与我相似的案例(例如 http.get Parse Error, code: 'HPE_UNEXPECTED_CONTENT_LENGTH' ),结论是有一个同时包含 Content-Length 和 Transfer-encoding: chunked headers existing together 的响应(这是一个错误)。我的回复没有这个错误,但我想知道声明的内容长度是否错误,或者在某处的回复中是否存在虚假的 cr/lf。我希望我可以在 IntelliJ 中调试这个假设

IntelliJ debugging a node application

关于json - NodeJS,如何在 GET 请求时调试 TLSSocket.socketOnData 的解析错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41773227/

相关文章:

node.js - 如何在 Mongoose 中仅获取子文档的一项?

javascript - 使用nodejs mysql模块从mysql获取JSON数据

java - NetBeans : Unable to attach debugger (getting Connection refused error)

json - 无法迭代 Node 、express 应用程序中的 json 对象

node.js - fetch POST 在 Express API 服务器 React FrontEnd 中仅返回 _id 对象

ajax - 如何使用DOJO AJAX和REST解析JSON

oracle - SQL Developer 调试所有包调用

ios - 在 iPhone 上调试卡住 safari

javascript - 使用变量作为key解析json

javascript - 无需多次中间检查即可获取嵌套的 JSON/对象值?