web-dev-qa-db-fra.com

Obtenir du contenu binaire dans node.js avec http.request

Je souhaite récupérer des données binaires à partir d'une demande https.

J'ai trouvé une question similaire qui utilise la méthode de demande, Obtenir le contenu binaire dans Node.js en utilisant la demande , dit le paramètre le codage en null devrait fonctionner, mais ce n'est pas le cas.

options = {
    hostname: urloptions.hostname,
    path: urloptions.path,
    method: 'GET',
    rejectUnauthorized: false,
    encoding: null
};

req = https.request(options, function(res) {
    var data;
    data = "";
    res.on('data', function(chunk) {
        return data += chunk;
    });
    res.on('end', function() {
        return loadFile(data);
    });
    res.on('error', function(err) {
        console.log("Error during HTTP request");
        console.log(err.message);
    });
})

Edit: définir l'encodage sur 'binaire' ne fonctionne pas non plus

33
edi9999

La réponse acceptée n'a pas fonctionné pour moi (c'est-à-dire, définir l'encodage sur binaire), même l'utilisateur qui a posé la question a mentionné que cela ne fonctionnait pas.

Voici ce qui a fonctionné pour moi, tiré de: http://chad.pantherdev.com/node-js-binary-http-streams/

http.get(url.parse('http://myserver.com:9999/package'), function(res) {
    var data = [];

    res.on('data', function(chunk) {
        data.Push(chunk);
    }).on('end', function() {
        //at this point data is an array of Buffers
        //so Buffer.concat() can make us a new Buffer
        //of all of them together
        var buffer = Buffer.concat(data);
        console.log(buffer.toString('base64'));
    });
});

Modifier: Mettre à jour la réponse suite à une suggestion de point-virgule

60
Guaycuru

Vous devez définir le codage pour répondre, pas demander:

req = https.request(options, function(res) {
    res.setEncoding('binary');

    var data = [ ];

    res.on('data', function(chunk) {
        data.Push(chunk);
    });
    res.on('end', function() {
        var binary = Buffer.concat(data);
        // binary is your data
    });
    res.on('error', function(err) {
        console.log("Error during HTTP request");
        console.log(err.message);
    });
});

Voici une réponse utile: Écriture d'image sur le serveur local

15
moka

Fonctionnant sur NodeJS 6.10 (et 8.10, testé en février 2019) dans l'environnement AWS Lambda, aucune des solutions ci-dessus ne me convient.

Ce qui a fonctionné pour moi était le suivant:

https.get(opt, (res) => {
    res.setEncoding('binary');
    let chunks = [];

    res.on('data', (chunk) => {
        chunks.Push(Buffer.from(chunk, 'binary'));
    });

    res.on('end', () => {
        let binary = Buffer.concat(chunks);
        // binary is now a Buffer that can be used as Uint8Array or as
        // any other TypedArray for data processing in NodeJS or 
        // passed on via the Buffer to something else.
    });
});

Prenez note du res.setEncoding ('binaire'); et Buffer.from (chunk, 'binary') lines. L'un définit l'encodage de la réponse et l'autre crée un objet Buffer à partir de la chaîne fournie dans l'encodage spécifié précédemment.

10
Pärt Johanson

Pärt Johanson J'aimerais pouvoir commenter juste pour vous remercier de m'avoir sauvé de la boucle récursive dans laquelle j'ai été toute la journée à arracher mes cheveux et à lire les documents de nœud (incroyablement inutiles) à ce sujet, encore et encore. Après avoir trouvé votre réponse, je suis allé fouiller dans les documents, et je ne trouve même pas la méthode res.setEncoding Documentée n'importe où! C'est juste montré dans le cadre de deux exemples, dans lesquels ils appellent res.setEncoding('utf8'); Où avez-vous trouvé cela ou comment l'avez-vous compris!?

Comme je n'ai pas assez de réputation pour commenter, je vais au moins apporter quelque chose d'utile à ma réponse: la réponse de Pärt Johanson a fonctionné à 100% pour moi, je l'ai juste un peu ajustée pour mes besoins parce que je l'utilise pour télécharger et évaluez un script hébergé sur mon serveur (et compilé avec nwjc) en utilisant nw.Window.get().evalNWBin() sur NWJS 0.36.4/Node 11.11.0:

let opt = {...};
let req = require('https').request(opt, (res) => {
  // server error returned
  if (200 !== res.statusCode) {
    res.setEncoding('utf8');
    let data = '';
    res.on('data', (strData) => {
      data += strData;
    });
    res.on('end', () => {
      if (!res.complete) {
        console.log('Server error, incomplete response: ' + data);
      } else {
        console.log('Server error, response: ' + data);
      }
    });
  }
  // expected response
  else {
    res.setEncoding('binary');
    let data = [];
    res.on('data', (binData) => {
      data.Push(Buffer.from(binData, 'binary'));
    });
    res.on('end', () => {
      data = Buffer.concat(data);
      if (!res.complete) {
        console.log('Request completed, incomplete response, ' + data.length + ' bytes received);
      } else {
        console.log('Request completed, ' + data.length + ' bytes received');
        nw.Window.get().evalNWBin(null, data);
      }
    });
  }
};

Edit: P.S. J'ai posté cela juste au cas où quelqu'un voudrait savoir comment gérer une réponse non binaire - mon code réel va un peu plus loin et vérifie l'en-tête du type de contenu de la réponse pour analyser JSON (échec prévu, c'est-à-dire 400, 401, 403) ou HTML ( panne inattendue, c.-à-d. 404 ou 500)

2
caffeinatedbits
  1. N'appelez pas la méthode setEncoding(), car par défaut, aucun encodage n'est attribué et les données de flux seront renvoyées en tant qu'objets Buffer
  2. Appelez Buffer.from() dans on.data méthode de rappel pour convertir la valeur chunk en un objet Buffer.
http.get('my_url', (response) => {
  const chunks = [];
  response.on('data', chunk => chunks.Push(Buffer.from(chunk))) // Converte `chunk` to a `Buffer` object.
    .on('end', () => {
      const buffer = Buffer.concat(chunks);
      console.log(buffer.toString('base64'));
    });
});
0
Naijia Liu