Node.js HTTPS.get返回状态代码406

时间:2018-02-06 20:06:47

标签: javascript node.js http https

我试图仅使用内置的HTTPS模块向API发出一个承诺的HPPTS请求。返回的状态代码是406,我也收到了缓冲区错误:

TypeError: buf.copy is not a function
at Function.Buffer.concat (buffer.js:240:9)
at IncomingMessage.<anonymous> (/var/task/index.js:562:41)
at emitNone (events.js:72:20)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:905:12)
at nextTickCallbackWith2Args (node.js:437:9)
at process._tickDomainCallback (node.js:392:17)

这是我的功能:

function createRequest(url, body, callback){
  return new Promise(function(resolve, reject) {
    try{
        var parsedUrl = Url.parse(url, true, true);
    }
    catch(e) {
        console.log("URL parsing error");
    }

    try{
    https.get({
        hostname: parsedUrl.hostname,
        path: parsedUrl.path,
        headers: {
            'Content-Type': 'application/json'
        }
    }, function(response) {
    console.log(response.statusCode);
    response.setEncoding("utf8");
    var responseBuffer = [];
    response.on('data', function(d) {
        responseBuffer.push(d);
    });

    response.on('end', function() {
        var responseString = Buffer.concat(responseBuffer);
        callback(JSON.parse(responseString));
        resolve(responseString);
    });

    response.on('error', (e) => {
        reject(e);
    });
  });
  } catch(e){
    console.log(e);
  }
  });
}

在响应结束时,responseText只是一个空格。

那我在这里做错了什么?感谢您的帮助和耐心。

编辑:另外值得注意的是,如果我将Buffer.concat行更改为var responseString = responseBuffer.join();错误变成了这个,在回调上(JSON.parse(responseString));线。

SyntaxError: Unexpected end of input
at Object.parse (native)
at IncomingMessage.<anonymous> (/var/task/index.js:564:27)
at emitNone (events.js:72:20)
at IncomingMessage.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:905:12)
at nextTickCallbackWith2Args (node.js:437:9)
at process._tickDomainCallback (node.js:392:17)

2 个答案:

答案 0 :(得分:1)

看起来有两个不同的问题:

  • 当您致电response.setEncoding('utf8')时,节点会自动将传入的数据转换为字符串。这意味着data事件会使用字符串触发,而不是Buffer s。

    这意味着您需要将流保持在二进制模式(通过不调用setEncoding),保留缓冲区数组,然后连接并在最后将它们转换为字符串。

    response.on('end', function() {
      try {
        var responseString = Buffer.concat(responseBuffer).toString('utf8');
        resolve(JSON.parse(responseString));
      } catch(ex) {
        reject(ex);
      }
    });
    

    ...或保持setEncoding调用并执行简单的字符串连接。

    response.on('data', function(str) {
      responseString += str;
    });
    

    我推荐前者以获得更好的性能(节点必须做一些内部缓冲来处理流模式下的多字节字符)。

  • 您正在使用的API返回406( Not Acceptable )。这可能意味着您必须在请求中提供Accept标头。

答案 1 :(得分:0)

根据以下文档,Buffer.concat需要List of Buffer or Uint8Array作为参数

https://nodejs.org/api/buffer.html#buffer_class_method_buffer_concat_list_totallength

在将字符串推送到数组之前,您可以尝试使用以下内容将字符串转换为缓冲区。

response.on('data', function(d) {
    responseBuffer.push(Buffer.from(d, 'utf8'));
});

检查此处的详细问题

https://github.com/nodejs/node/issues/4949

希望有所帮助