Question Comment extrayez-vous les données POST dans Node.js?


Comment extrayez-vous les données de formulaire (form[method="post"]) et les téléchargements de fichiers envoyés à partir du HTTP POST méthode dans Node.js?

J'ai lu la documentation, googlé et trouvé rien.

function (request, response) {
    //request.post????
}

Y a-t-il une bibliothèque ou un hack?


500
2017-11-28 07:16


origine


Réponses:


Si tu utilises Express (développement web de haute performance et de haute qualité pour Node.js), vous pouvez le faire:

HTML:

<form method="post" action="/">
    <input type="text" name="user[name]">
    <input type="text" name="user[email]">
    <input type="submit" value="Submit">
</form>

JavaScript:

app.use(express.bodyParser());

app.post('/', function(request, response){
    console.log(request.body.user.name);
    console.log(request.body.user.email);
});

MISE À JOUR le 1 / juin / 2016:

La méthode ci-dessus est une utilisation obsolète maintenant:

const bodyParser = require("body-parser");

/** bodyParser.urlencoded(options)
 * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST)
 * and exposes the resulting object (containing the keys and values) on req.body
 */
app.use(bodyParser.urlencoded({
    extended: true
}));

/**bodyParser.json(options)
 * Parses the text as JSON and exposes the resulting object on req.body.
 */
app.use(bodyParser.json());

app.post("/", function (req, res) {
    console.log(req.body.user.name)
});

429
2017-11-28 10:45



Vous pouvez utiliser le querystring module:

var qs = require('querystring');

function (request, response) {
    if (request.method == 'POST') {
        var body = '';

        request.on('data', function (data) {
            body += data;

            // Too much POST data, kill the connection!
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6)
                request.connection.destroy();
        });

        request.on('end', function () {
            var post = qs.parse(body);
            // use post['blah'], etc.
        });
    }
}

Maintenant, par exemple, si vous avez un input champ avec nom age, vous pouvez y accéder en utilisant la variable post:

console.log(post.age);

641
2017-11-30 02:44



Assurez-vous de tuer la connexion si quelqu'un essaie d'inonder votre RAM!

var qs = require('querystring');

function (request, response) {
    if (request.method == 'POST') {
        var body = '';
        request.on('data', function (data) {
            body += data;
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6) { 
                // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
                request.connection.destroy();
            }
        });
        request.on('end', function () {

            var POST = qs.parse(body);
            // use POST

        });
    }
}

133
2017-12-27 01:06



Voici un très simple wrapper sans framework basé sur les autres réponses et articles postés ici:

var http = require('http');
var querystring = require('querystring');

function processPost(request, response, callback) {
    var queryData = "";
    if(typeof callback !== 'function') return null;

    if(request.method == 'POST') {
        request.on('data', function(data) {
            queryData += data;
            if(queryData.length > 1e6) {
                queryData = "";
                response.writeHead(413, {'Content-Type': 'text/plain'}).end();
                request.connection.destroy();
            }
        });

        request.on('end', function() {
            request.post = querystring.parse(queryData);
            callback();
        });

    } else {
        response.writeHead(405, {'Content-Type': 'text/plain'});
        response.end();
    }
}

Exemple d'utilisation:

http.createServer(function(request, response) {
    if(request.method == 'POST') {
        processPost(request, response, function() {
            console.log(request.post);
            // Use request.post here

            response.writeHead(200, "OK", {'Content-Type': 'text/plain'});
            response.end();
        });
    } else {
        response.writeHead(200, "OK", {'Content-Type': 'text/plain'});
        response.end();
    }

}).listen(8000);

86
2017-08-18 22:37



Ce sera plus propre si vous encoder vos données à JSON, puis envoyez-le à Node.js.

function (req, res) {
    if (req.method == 'POST') {
        var jsonString = '';

        req.on('data', function (data) {
            jsonString += data;
        });

        req.on('end', function () {
            console.log(JSON.parse(jsonString));
        });
    }
}

70
2017-07-22 08:55



Beaucoup de réponses ne sont plus de bonnes pratiques ou n'expliquent rien, c'est pourquoi j'écris ceci.

Lorsque le callback de http.createServer est appelé, c'est quand le serveur a réellement reçu tous les en-têtes pour la requête, mais il est possible que les données n'aient pas encore été reçues, donc nous devons l'attendre. le Objet de requête http (une instance http.IncomingMessage) est en fait un lisible  courant. Dans les flux lisibles chaque fois qu'un bloc de données arrive, un data  l'événement est émis(en supposant que vous avez enregistré un rappel) et quand tous les morceaux sont arrivés end l'événement est émis. Voici un exemple d'écoute des événements:

http.createServer((request, response) => {
  console.log('Now we have a http message with headers but no data yet.');
  request.on('data', chunk => {
    console.log('A chunk of data has arrived: ', chunk);
  });
  request.on('end', () => {
    console.log('No more data');
  })
}).listen(8080)

Si vous essayez ceci, vous remarquerez que les morceaux sont tampons. Si vous ne traitez pas de données binaires et que vous devez travailler avec des chaînes, je vous suggère d’utiliser request.setEncoding méthode qui permet au flux d'émettre des chaînes interprétées avec le codage donné et gère correctement les caractères multi-octets.

Maintenant, vous n'êtes probablement pas intéressé par chaque morceau par lui-même, donc dans ce cas, vous voulez probablement le mettre en mémoire tampon comme ceci:

http.createServer((request, response) => {
  const chunks = [];
  request.on('data', chunk => chunks.push(chunk));
  request.on('end', () => {
    const data = Buffer.concat(chunks);
    console.log('Data: ', data);
  })
}).listen(8080)

Ici Buffer.concat est utilisé, qui concatène simplement tous les tampons et renvoie un gros tampon. Vous pouvez également utiliser le module de concat-stream qui fait la même chose:

const http = require('http');
const concat = require('concat-stream');
http.createServer((request, response) => {
  concat(request, data => {
    console.log('Data: ', data);
  });
}).listen(8080)

Si vous essayez d’accepter la soumission POST des formulaires HTML sans fichiers ni transfert jQuery ajax appels avec le type de contenu par défaut, puis le type de contenu est application/x-www-form-urlencoded avec uft-8 codage. Vous pouvez utiliser le module querystring pour le dé-sérialiser et accéder aux propriétés:

const http = require('http');
const concat = require('concat-stream');
const qs = require('querystring');
http.createServer((request, response) => {
  concat(request, buffer => {
    const data = qs.parse(buffer.toString());
    console.log('Data: ', data);
  });
}).listen(8080)

Si votre type de contenu est JSON, vous pouvez simplement utiliser JSON.parse au lieu de qs.parse.

Si vous traitez des fichiers ou manipulez un type de contenu en plusieurs parties, alors dans ce cas, vous devriez utiliser quelque chose comme redoutable qui supprime toute la douleur de traiter avec. Jettes un coup d'oeil à cette autre réponse du mien où j'ai posté des liens utiles et des modules pour le contenu multipart.

Si vous ne souhaitez pas analyser le contenu mais le transmettre à un autre, par exemple, l'envoyer à une autre requête http en tant que donnée ou l'enregistrer dans un fichier que je suggère le canaliser plutôt que de le mettre en mémoire tampon, car il y aura moins de code, la pression de retour sera meilleure, cela prendra moins de mémoire et dans certains cas plus vite.

Donc, si vous voulez enregistrer le contenu dans un fichier:

 http.createServer((request, response) => {
   request.pipe(fs.createWriteStream('./request'));
 }).listen(8080)

Comme d'autres réponses l'ont noté, gardez à l'esprit que les clients malveillants peuvent vous envoyer une quantité énorme de données pour faire planter votre application ou remplir votre mémoire afin de protéger les requêtes émettant des données d'une certaine limite. Si vous n'utilisez pas une bibliothèque pour gérer les données entrantes. Je suggère d'utiliser quelque chose comme débitmètre qui peut annuler la requête si elle atteint la limite spécifiée:

limitedStream = request.pipe(meter(1e7));
limitedStream.on('data', ...);
limitedStream.on('end', ...);

ou

request.pipe(meter(1e7)).pipe(createWriteStream(...));

ou

concat(request.pipe(meter(1e7)), ...);

Essayez également d'utiliser des modules npm plutôt que de les mettre en œuvre seuls, car ils traiteront probablement mieux les cas limites. Pour exprimer je suggère d'utiliser body-parser. Pour koa, il y a un module similaire.

Si vous n'utilisez pas de framework, corps c'est assez bon


60
2018-01-07 13:04



Pour tous ceux qui se demandent comment faire cette tâche triviale sans avoir à installer un framework web, j'ai réussi à le faire ensemble. À peine la production est prête, mais cela semble fonctionner.

function handler(req, res) {
    var POST = {};
    if (req.method == 'POST') {
        req.on('data', function(data) {
            data = data.toString();
            data = data.split('&');
            for (var i = 0; i < data.length; i++) {
                var _data = data[i].split("=");
                POST[_data[0]] = _data[1];
            }
            console.log(POST);
        })
    }
}

29
2017-10-16 00:20



Vous pouvez utiliser body-parser, le middleware d'analyse de corps Node.js.

Premier chargement body-parser 

$ npm install body-parser --save

Un exemple de code

var express = require('express')
var bodyParser = require('body-parser')

var app = express()

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())


app.use(function (req, res) {
  var post_data = req.body;
  console.log(post_data);
})

Plus de documentation peut être trouvée ici


8
2017-10-09 18:38



Voici comment vous pouvez le faire si vous utilisez nœud-formidable:

var formidable = require("formidable");

var form = new formidable.IncomingForm();
form.parse(request, function (err, fields) {
    console.log(fields.parameter1);
    console.log(fields.parameter2);
    // ...
});

5
2018-05-20 22:59



Référence: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // at this point, `body` has the entire request body stored in it as a string
});

5
2018-01-24 13:05