【问题标题】:https.get() works https.request() timeouts with events.js:136 throw er; // Unhandled 'error' eventhttps.get() 与 events.js:136 throw er 一起工作 https.request() 超时; // 未处理的“错误”事件
【发布时间】:2018-03-15 13:33:13
【问题描述】:

在下面的示例中,我尝试调用测试 REST api:api.postcodes.io。使用 https.get() 的函数工作正常,使用 https.request() 的函数挂起然后超时。这有点奇怪。

有人知道会发生什么吗?我尝试了无数种使用 https.request() 的方法,它们的行为方式都相同。示例代码:

    "use strict";
//
// This is a working example of https.get()
//
const https = require("https");

function https_get()
{
    console.log("https_get()");
    const url = "https://api.postcodes.io/postcodes/BL34HG";
    https.get(url, res => {
      res.setEncoding("utf8");
      let body = "";
      res.on("data", data => {
        body += data;
      });
      res.on("end", () => {
        body = JSON.parse(body);
        console.log(body);

      });
    });
}

// This doesn't work. 
function https_request()
{
    console.log("https_request()");
    var headers= {
            "Content-Type": "application/json"
        };
    var options = {
            "method": "GET",
            "host": "api.postcodes.io",     // Don't include https:// as throws an error
            "path": "/postcodes/SW1A1AA",
            "headers": headers
    };

    console.log("-------------------------------")
    console.log("failed request options:",options); 
    console.log("-------------------------------")

    https.request(options, res => {

        if (res.statusCode != 200) {
            console.log("\tHTTPS statuscode not 200: ",res.statusCode);
            callback(false);
            return;
        }
        console.log("res.StatusCode:", res.StatusCode);
        res.setEncoding("utf8");
        let body = "";

        res.on("data", data => {
          body += data;
        });

        res.on("end", () => {
          body = JSON.parse(body);
          console.log(body);
        });

        res.on("error", e => {
            console.log("res.on('error')res.StatusCode:", e.message);
        });

    }); // End https.request()
}

https_get(); // This Works OK.

https_request(); // This doesn't work, it times-out with events.js:136 throw er; // Unhandled 'error' event ^ Error: socket hang up

程序的控制台输出是这样的:

https_get()
https_request()
-------------------------------
failed request options: { method: 'GET',
  host: 'api.postcodes.io',
  path: '/postcodes/SW1A1AA',
  headers: { 'Content-Type': 'application/json' } }
-------------------------------
{ status: 200,
  result: 
   { postcode: 'BL3 4HG',
     quality: 1,
     eastings: 369619,
     northings: 407887,

...

        ccg: 'E38000016',
        nuts: 'UKD36' } } }

events.js:136
      throw er; // Unhandled 'error' event
      ^

Error: socket hang up
    at createHangUpError (_http_client.js:330:15)
    at TLSSocket.socketOnEnd (_http_client.js:423:23)
    at TLSSocket.emit (events.js:164:20)
    at endReadableNT (_stream_readable.js:1054:12)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)

【问题讨论】:

    标签: node.js httprequest


    【解决方案1】:

    为您的请求添加错误处理程序,并调用req.end()

    const req = https.request(options, res => {
        ...
    })
    
    req.on('error', (e) => {
        console.error(e);
    });
    
    req.end();
    

    The Node docs explain why:

    请注意,在示例中调用了 req.end()。用 http.request() 之一 必须始终调用 req.end() 来表示请求的结束——即使 没有数据写入请求正文。

    【讨论】:

    • 谢谢。现在您已经指出了问题,这似乎很明显。
    • 哦,天哪,我不认为这很明显!!!在the docs 内部(在撰写本文时)有几个示例将req.end() 排除在示例之外,并且警告文本仅出现在http.request 页面上(不在https.request 上)。因为https.get() 在没有明确调用 end 的情况下工作,而我正在发送相同的选项对象!
    猜你喜欢
    • 2018-05-04
    • 2019-08-21
    • 2018-11-19
    • 2020-12-12
    • 2019-11-10
    • 2018-07-23
    • 2015-03-01
    • 2019-01-27
    • 2017-06-23
    相关资源
    最近更新 更多