简体   繁体   中英

Node.js HTTPS.get returns a status code 406

I'm trying to make a promise-ified HPPTS request to an API, using only the built in HTTPS module. The returned status code is 406, and I'm also getting a buffer error:

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)

Here's my function:

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);
  }
  });
}

At the response end, the responseText is just a single space.

So what am I doing wrong here? Thank you for the help and patience.

EDIT: Also worth noting, if I change the Buffer.concat line to var responseString = responseBuffer.join(); the error becomes this, on the callback(JSON.parse(responseString)); line.

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)

It looks like there are 2 separate problems:

  • When you call response.setEncoding('utf8') , node automatically converts the incoming data into strings. This means that the data event fires with strings, not Buffer s.

    This means you either need to keep the stream in binary mode (by not calling setEncoding ), keep the array of buffers, and then concatenate and convert them to a string at the end.

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

    ...or keep the setEncoding call and do simple string concatenation.

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

    I recommend the former for better performance (node has to do some internal buffering to deal with multibyte characters in streaming mode).

  • The API you're using is returning a 406 ( Not Acceptable ). This likely means you must supply an Accept header in your request.

Based on the following doc, Buffer.concat needs List of Buffer or Uint8Array as parameter

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

You can try something like the following to convert the string to buffer before push it to your array.

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

Check the detailed issue here

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

Hope it helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM