Comment traiter les données POST dans Node.js?

638

Comment extraire des données de formulaire ( form[method="post"]) et des téléchargements de fichiers envoyés à partir de la POSTméthode HTTP dans Node.js ?

J'ai lu la documentation, recherché sur Google et rien trouvé.

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

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

Ming-Tang
la source

Réponses:

553

Si vous utilisez Express (développement Web haute performance et haut de gamme 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>

Client API:

fetch('/', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        user: {
            name: "John",
            email: "[email protected]"
        }
    })
});

Node.js: (depuis Express v4.16.0)

// Parse URL-encoded bodies (as sent by HTML forms)
app.use(express.urlencoded());

// Parse JSON bodies (as sent by API clients)
app.use(express.json());

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

Node.js: (pour Express <4.16.0)

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)
});
Baggz
la source
45
La fonctionnalité se trouve en fait dans le module BodyParser de connect, si vous souhaitez utiliser un point d'entrée de niveau inférieur.
Julian Birch
14
Je suis confus. Comment name = "user [email]" correspond-il à request.body.email?
sbose
36
Dieu!! je deviens fou d'avoir à lire 3 doumentations en même temps pour le même framework: / nodejs.org/api/http.html , senchalabs.org/connect & expressjs.com/guide.html
Salman von Abbas
15
Cela n'a pas fonctionné pour moi jusqu'à ce que j'ajoute app.use(express.bodyParser());.
pettys
13
Express est au nœud ce que jQuery est au JS côté client. Chaque fois que j'aide Google pour le noeud, je reçois ces boiteux "use express!" réponses. Est-il vraiment si difficile d'analyser les données des publications qu'il justifie l'installation d'un framework Web complet?
Shawn Whinnery
710

Vous pouvez utiliser le querystringmodule:

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 inputchamp avec un nom age, vous pouvez y accéder en utilisant la variable post:

console.log(post.age);
Casey Chu
la source
8
@thejh Hm, c'est un bon point. Il ne devrait pas être difficile d'ajouter cela, cependant, je vais donc laisser de côté l'exemple pour garder les choses simples.
Casey Chu
72
Le développement du serveur web node.js est en proie à middlewarez qui vous oblige à les étudier pendant des heures pour vous faire gagner quelques minutes de codage. Sans parler de la documentation limitée que presque tous proposent. Et votre candidature finit par s'appuyer sur les critères d'autres personnes, pas sur les vôtres. Plus un certain nombre de problèmes de performances.
Juan Lanus
4
var POST = qs.parse(body); // use POST uniquement pour les noobs comme moi: lorsque le nom du champ de texte saisi est "utilisateur", Post.useraffichera les données de ce champ. par exempleconsole.log(Post.user);
Michael Moeller
5
Vous pouvez également utiliser le readablerappel au lieu de créer les données dans une chaîne de corps. Une fois tiré, le corps est disponible viarequest.read();
Thomas Fankhauser
4
Notez que cela req.connection.destroy(); n'empêche pas l'exécution des rappels! Par exemple, le rappel "à la fin" sera exécuté avec le corps tronqué! Ce n'est probablement pas ce que vous voulez ...
collimarco
149

Assurez-vous de couper 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

        });
    }
}
thejh
la source
53
Vous pouvez également retourner le code d'erreur HTTP 413 (Entité de requête trop grande)
néoascétique
1
@SSHThis: Non, c'est 1 * 10 ^ 6 = 1000000.
thejh
@tq: dans ce cas, POST [nom] (par exemple POST ["foo"]).
thejh
2
var POST = qs.parse(body); // use POST uniquement pour les noobs: lorsque le nom du champ de texte saisi est "utilisateur", Post.user affichera les données de ce champ. par exemple console.log (Post.user);
Michael Moeller
2
Quelqu'un peut-il m'aider, si je poste {'Name': 'Joe'} Je reçois {{'Name': 'Joe'}: ''} après qs.Parse (POST) ...
Matt Canty
118

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

Les bases

Lorsque le rappel de http.createServer est appelé, c'est lorsque le serveur a effectivement reçu tous les en-têtes de la demande, mais il est possible que les données n'aient pas encore été reçues, nous devons donc l'attendre. L' objet de requête http (une instance http.IncomingMessage) est en fait un flux lisible . Dans les flux lisibles chaque fois qu'un bloc de données arrive, un événement est émis (en supposant que vous y avez enregistré un rappel) et lorsque tous les blocs sont arrivés, un événement est émis. Voici un exemple sur la façon dont vous écoutez les événements:data end

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)

Conversion de tampons en chaînes

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

Morceaux tampons

Maintenant, vous n'êtes probablement pas intéressé par chaque morceau par lui-même, donc dans ce cas, vous voulez probablement le tamponner 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 retourne un gros tampon. Vous pouvez également utiliser le module concat-stream qui fait de même:

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

Analyse du contenu

Si vous essayez d'accepter la soumission POST de formulaires HTML sans fichier ou de passer des appels jQuery ajax avec le type de contenu par défaut, le type de contenu est application/x-www-form-urlencodedavec uft-8codage. 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 à la place, 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 devez utiliser quelque chose comme formidable qui enlève toute la douleur de le traiter. Jetez un oeil à cette autre réponse à moi où j'ai publié des liens et des modules utiles pour le contenu en plusieurs parties.

Tuyauterie

Si vous ne voulez pas analyser le contenu mais plutôt le transmettre ailleurs, par exemple l'envoyer à une autre requête http en tant que données ou l'enregistrer dans un fichier, je suggère de le canaliser plutôt que de le mettre en mémoire tampon, car ce sera moins code, gère mieux la contre-pression, cela prendra moins de mémoire et dans certains cas plus rapidement.

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

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

Limiter la quantité de données

Comme d'autres réponses l'ont noté, gardez à l'esprit que les clients malveillants peuvent vous envoyer une énorme quantité de données pour bloquer votre application ou remplir votre mémoire afin de vous assurer que vous supprimez les demandes qui émettent des données dépassent une certaine limite. Si vous n'utilisez pas de bibliothèque pour gérer les données entrantes. Je suggère d'utiliser quelque chose comme stream-meter qui peut abandonner la demande s'il 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)), ...);

Modules NPM

Alors que j'ai décrit ci-dessus comment utiliser le corps de la requête HTTP, pour simplement mettre en mémoire tampon et analyser le contenu, je suggère d'utiliser l'un de ces modules plutôt que de l'implémenter par vous-même car ils traiteront probablement mieux les cas marginaux. Pour exprimer, je suggère d'utiliser l' analyseur corporel . Pour koa, il existe un module similaire .

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

Farid Nouri Neshat
la source
Merci, j'ai utilisé votre code et j'ai reçu de mystérieux messages en double. Se pourrait-il que la variable requestsoit réutilisée et qu'elle request.on('end')soit invoquée plusieurs fois? Comment puis-je éviter cela?
Yan King Yin
Je ne peux pas dire pourquoi sans voir votre code. Notez que pour chaque demande, request.on('end', ...)sera appelé.
Farid Nouri Neshat
C'est probablement sans rapport avec votre code, je fais des événements envoyés par le serveur et j'ai peut-être foiré ... votre code fonctionne bien, merci quand même :)
Yan King Yin
Comment cela affecte-t-il les performances par rapport au traitement d'une demande GET sans gestionnaire «final», c'est-à-dire sans mise en mémoire tampon de blocs?
JSON
1
Ceci est la meilleure réponse à la question. 🧐
montréaliste
103

Voici un wrapper sans cadre très simple basé sur les autres réponses et articles publié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);
Mahn
la source
Cette vérification ne devrait-elle pas être déplacée vers un middleware séparé afin qu'il puisse vérifier les demandes trop volumineuses sur toutes les demandes de post / put
Pavel Nikolov
@PavelNikolov, cela est principalement destiné aux travaux rapides et sales, sinon il vaut probablement mieux utiliser Express comme le recommande la réponse acceptée ici (qui s'occupe probablement de la gestion des demandes volumineuses également). N'hésitez pas à le modifier et à le "bifurquer" à votre guise.
Mahn
Qu'en est-il de la méthode .read ()? N'est-ce pas pris en charge par le module http? Par exemple. response.read ()
BT
Hé, juste curieux - pourquoi avez-vous placé la charge utile dans l'objet de réponse (response.post) plutôt que dans l'objet de demande?
Jotham
@Jotham bonne question ... Je ne sais pas pourquoi je ne l'ai pas remarqué plus tôt, mais il n'y a aucune raison pour que ce soit response.postplutôt que le plus logique request.post. J'ai mis à jour le message.
Mahn
83

Il sera plus propre si vous encodez vos données en JSON , puis envoyez-les à 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));
        });
    }
}
Lewis
la source
1
C'est ce qui a fonctionné pour moi. Il s'avère que les autres solutions ont renvoyé une chaîne qui ressemblait à JSON mais n'a pas été analysée. Au lieu de cela qs.parse(), a JSON.parse()transformé le corps en quelque chose utilisable. Exemple:, var post = JSON.parse(body);puis accédez aux données avec post.fieldname. (Morale de l'histoire, si vous êtes confus au sujet de ce que vous voyez, n'oubliez pas typeof!)
wmassingham
12
Eh bien, sachez que vous devez essayer d'attraper la fonction JSON.parse parce que si je veux planter votre application, envoyez simplement un corps avec du texte brut.
ecarrizo
Vous devez utiliser request.setEncodingpour faire fonctionner correctement sinon il pourrait ne pas gérer correctement les caractères non ascii.
Farid Nouri Neshat
37

Pour tous ceux qui se demandent comment faire cette tâche insignifiante sans installer de cadre Web, j'ai réussi à le faire ensemble. À peine prêt pour la production mais il 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);
        })
    }
}
Shawn Whinnery
la source
Enfin, une solution complète pour ce problème étrange .. également la réponse précédente a beaucoup aidé à comprendre pourquoi il n'y avait pas de données à l'intérieur de la demande lorsque le rappel commence .. Merci beaucoup!
luis-br
3
1) Cette réponse suppose que les données sont une chaîne. Mauvaise hypothèse, dans un cas général. 2) Cette réponse suppose que les données arrivent en un seul bloc. Sinon, la division par '=' donnera un résultat imprévisible. Mauvaise hypothèse, dans un cas général.
Konstantin
@Konstantin En fait, cette réponse suppose que les données sont un tampon. Regarde ça. stackoverflow.com/questions/14551194/… Aussi cela. millermedeiros.github.io/mdoc/examples/node_api/doc/…
Shawn Whinnery
16

Vous pouvez utiliser body-parserle middleware d'analyse du corps Node.js.

Première charge 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

code source
la source
9

Voici comment vous pouvez le faire si vous utilisez node-formidable :

var formidable = require("formidable");

var form = new formidable.IncomingForm();
form.parse(request, function (err, fields) {
    console.log(fields.parameter1);
    console.log(fields.parameter2);
    // ...
});
Dmitry Efimenko
la source
J'ai un problème avec le chemin d'accès, lorsque j'essaie d'utiliser le chemin d'accès ou le chemin d'accès + nom pour accéder au fichier avec lwip.open (chemin d'accès ou chemin d'accès + nom, j'obtiens une erreur en tant qu'image non obtenue.
Lion789
7

Si vous préférez utiliser Node.js pur, vous pouvez extraire les données POST comme indiqué ci-dessous:

// Dependencies
const StringDecoder = require('string_decoder').StringDecoder;
const http = require('http');

// Instantiate the HTTP server.
const httpServer = http.createServer((request, response) => {
  // Get the payload, if any.
  const decoder = new StringDecoder('utf-8');
  let payload = '';

  request.on('data', (data) => {
    payload += decoder.write(data);
  });

  request.on('end', () => {
    payload += decoder.end();

    // Parse payload to object.
    payload = JSON.parse(payload);

    // Do smoething with the payload....
  });
};

// Start the HTTP server.
const port = 3000;
httpServer.listen(port, () => {
  console.log(`The server is listening on port ${port}`);
});

Oleksii Trekhleb
la source
6

1) Installez à 'body-parser'partir de npm.

2) Puis dans votre app.ts

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

3) alors vous devez écrire

app.use(bodyParser.json())

dans le module app.ts

4) Gardez à l'esprit que vous incluez

app.use(bodyParser.json())

en haut ou avant toute déclaration de module.

Ex:

app.use(bodyParser.json())
app.use('/user',user);

5) Ensuite, utilisez

var postdata = req.body;
Er Shubham Patidar
la source
5

Si vous ne voulez pas segmenter vos données avec le datarappel, vous pouvez toujours utiliser le readablerappel comme ceci:

// Read Body when Available
request.on("readable", function(){
  request.body = '';
  while (null !== (request.body += request.read())){}
});

// Do something with it
request.on("end", function(){
  request.body //-> POST Parameters as String
});

Cette approche modifie la demande entrante, mais dès que vous avez terminé votre réponse, la demande sera récupérée, ce qui ne devrait pas poser de problème.

Une approche avancée serait de vérifier d'abord la taille du corps, si vous avez peur des corps énormes.

Thomas Fankhauser
la source
Une façon pratique de le faire, mais comment "vérifiez-vous d'abord la taille du corps" d'une manière qui ne peut pas être trompée par une demande malveillante?
doug65536
requestest un flux node.js normal, vous pouvez donc vérifier la request.headerslongueur du corps et annuler la demande si nécessaire.
Thomas Fankhauser
1
@ThomasFankhauser La longueur du corps dans l'en-tête peut ne pas être la valeur correcte ou même être présente. La bonne façon de le faire, c'est que lorsque le corps arrive et que vous le tamponnez, vous vérifiez la taille pour vous assurer qu'il ne dépasse pas la limite.
Farid Nouri Neshat
4

Il existe plusieurs façons de procéder. Cependant, le moyen le plus rapide que je connaisse est d'utiliser la bibliothèque Express.js avec body-parser.

var express = require("express");
var bodyParser = require("body-parser");
var app = express();

app.use(bodyParser.urlencoded({extended : true}));

app.post("/pathpostdataissentto", function(request, response) {
  console.log(request.body);
  //Or
  console.log(request.body.fieldName);
});

app.listen(8080);

Cela peut fonctionner pour les chaînes, mais je changerais plutôt bodyParser.urlencoded en bodyParser.json si les données POST contiennent un tableau JSON.

Plus d'informations: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/

nikodean2
la source
4

Vous devez recevoir les POSTdonnées par blocs en utilisantrequest.on('data', function(chunk) {...})

const http = require('http');

http.createServer((req, res) => {
    if (req.method == 'POST') {
        whole = ''
        req.on('data', (chunk) => {
            # consider adding size limit here
            whole += chunk.toString()
        })

        req.on('end', () => {
            console.log(whole)
            res.writeHead(200, 'OK', {'Content-Type': 'text/html'})
            res.end('Data received.')
        })
    }
}).listen(8080)

Vous devriez envisager d'ajouter une limite de taille à la position indiquée comme l' a suggéré le jh .

Zaz
la source
Est-ce plus sensible à une attaque de loris lent?
Nodejs est moins sensible aux loris lents que, par exemple, php - car il ne construit pas un grand objet de session autour de chaque connexion http. Cependant, il semble que ce code pourrait encore introduire une vulnérabilité de type loris lent. Cela pourrait être évité avec un setTimeoutqui met fin à la connexion après un certain laps de temps, si la demande complète n'est pas reçue dans cette fenêtre.
Gershom
4

Express v4.17.0

app.use(express.urlencoded( {extended: true} ))
antelove
la source
3

Si vous utilisez Express.js , avant de pouvoir accéder à req.body, vous devez ajouter le middleware bodyParser:

app.use(express.bodyParser());

Ensuite, vous pouvez demander

req.body.user
PatricioS
la source
La plupart des middlewares (comme bodyParser) ne sont plus fournis avec Express et doivent être installés séparément. Voir la réponse de @ nikodean2 ci-dessus pour une réponse plus récente
Jeff Collier
app.use (bodyParser ()); fonctionne mais me donne des messages d'erreur rouges de dépréciation
Chris Allinson
2

Et si vous ne souhaitez pas utiliser l'intégralité du framework comme Express, mais vous avez également besoin de différents types de formulaires, y compris les téléchargements, puis formelle peut être un bon choix.

Il est répertorié dans les modules Node.js

Pavel Koryagin
la source
1

J'ai trouvé une vidéo qui explique comment y parvenir: https://www.youtube.com/watch?v=nuw48-u3Yrg

Il utilise le module "http" par défaut avec les modules "querystring" et "stringbuilder". L'application prend deux nombres (en utilisant deux zones de texte) à partir d'une page Web et lors de la soumission, retourne la somme de ces deux (ainsi que la persistance des valeurs dans les zones de texte). C'est le meilleur exemple que j'ai pu trouver ailleurs.

Code source associé:

var http = require("http");
var qs = require("querystring");
var StringBuilder = require("stringbuilder");

var port = 9000;

function getCalcHtml(req, resp, data) {
    var sb = new StringBuilder({ newline: "\r\n" });
    sb.appendLine("<html>");
    sb.appendLine(" <body>");
    sb.appendLine("     <form method='post'>");
    sb.appendLine("         <table>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter First No: </td>");

    if (data && data.txtFirstNo) {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' value='{0}'/></td>", data.txtFirstNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter Second No: </td>");

    if (data && data.txtSecondNo) {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' value='{0}'/></td>", data.txtSecondNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td><input type='submit' value='Calculate' /></td>");
    sb.appendLine("             </tr>");

    if (data && data.txtFirstNo && data.txtSecondNo) {
        var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo);
        sb.appendLine("             <tr>");
        sb.appendLine("                 <td>Sum: {0}</td>", sum);
        sb.appendLine("             </tr>");
    }

    sb.appendLine("         </table>");
    sb.appendLine("     </form>")
    sb.appendLine(" </body>");
    sb.appendLine("</html>");
    sb.build(function (err, result) {
        resp.write(result);
        resp.end();
    });
}

function getCalcForm(req, resp, data) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    getCalcHtml(req, resp, data);
}

function getHome(req, resp) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>Home</title></head><body>Want to some calculation? Click <a href='/calc'>here</a></body></html>");
    resp.end();
}

function get404(req, resp) {
    resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>404</title></head><body>404: Resource not found. Go to <a href='/'>Home</a></body></html>");
    resp.end();
}

function get405(req, resp) {
    resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>405</title></head><body>405: Method not supported</body></html>");
    resp.end();
}

http.createServer(function (req, resp) {
    switch (req.method) {
        case "GET":
            if (req.url === "/") {
                getHome(req, resp);
            }
            else if (req.url === "/calc") {
                getCalcForm(req, resp);
            }
            else {
                get404(req, resp);
            }
            break;
        case "POST":
            if (req.url === "/calc") {
                var reqBody = '';
                req.on('data', function (data) {
                    reqBody += data;
                    if (reqBody.length > 1e7) { //10MB
                        resp.writeHead(413, 'Request Entity Too Large', { 'Content-Type': 'text/html' });
                        resp.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
                    }
                });
                req.on('end', function () {
                    var formData = qs.parse(reqBody);
                    getCalcForm(req, resp, formData);
                });
            }
            else {
                get404(req, resp);
            }
            break;
        default:
            get405(req, resp);
            break;
    }
}).listen(port);
user203687
la source
1

Pour ceux qui utilisent le téléchargement POST binaire brut sans surcharge de codage, vous pouvez utiliser:

client:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/api/upload", true);
var blob = new Uint8Array([65,72,79,74]); // or e.g. recorder.getBlob()
xhr.send(blob);

serveur:

var express = require('express');
var router = express.Router();
var fs = require('fs');

router.use (function(req, res, next) {
  var data='';
  req.setEncoding('binary');
  req.on('data', function(chunk) {
    data += chunk;
  });

  req.on('end', function() {
    req.body = data;
    next();
  });
});

router.post('/api/upload', function(req, res, next) {
  fs.writeFile("binaryFile.png", req.body, 'binary', function(err) {
    res.send("Binary POST successful!");
  });
});
lukyer
la source
1

Vous pouvez utiliser le middleware express , qui contient désormais un analyseur de corps. Cela signifie que tout ce que vous devez faire est le suivant:

import express from 'express'

const app = express()

app.use(express.json())

app.post('/thing', (req, res) => {
  console.log(req.body) // <-- this will access the body of the post
  res.sendStatus(200)
})

Cet exemple de code est ES6 avec Express 4.16.x

Beaucoup d'argent
la source
0

vous pouvez extraire le paramètre post sans utiliser express.

1: nmp install multiparty

2: importation multipartite. commevar multiparty = require('multiparty');

3: `

if(req.method ==='POST'){
   var form = new multiparty.Form();
   form.parse(req, function(err, fields, files) {
      console.log(fields['userfile1'][0]);
    });
    }

4: ET LE FORMULAIRE HTML EST.

<form method=POST enctype=multipart/form-data>
<input type=text name=userfile1><br>
<input type=submit>
</form>

J'espère que cela fonctionnera pour vous. Merci.

Maneesh Singh
la source
0

Limitez la taille du POST pour éviter d'inonder votre application de nœud. Il existe un excellent module de corps brut , adapté à la fois à l'express et à la connexion, qui peut vous aider à limiter la demande par taille et longueur.

EricSonaron
la source
0

S'il s'agit d'un téléchargement de fichier, le navigateur l'envoie généralement en tant que "multipart/form-data"type de contenu. Vous pouvez l'utiliser dans de tels cas

var multipart = require('multipart');
multipart.parse(req)

Référence 1

Référence 2

user3526
la source
0

Sur des champs de formulaire comme ceux-ci

   <input type="text" name="user[name]" value="MyName">
   <input type="text" name="user[email]" value="[email protected]">

certaines des réponses ci-dessus échoueront car elles ne prennent en charge que les données plates.

Pour l'instant j'utilise la réponse Casey Chu mais avec le "qs" au lieu du module "querystring". C'est également le module "body-parser" . Donc, si vous voulez des données imbriquées, vous devez installer qs.

npm install qs --save

Remplacez ensuite la première ligne comme:

//var qs = require('querystring');
var qs = require('qs'); 

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);
            console.log(post.user.name); // should work
            // use post['blah'], etc.
        });
    }
}
Geza Turi
la source
0

Vous pouvez facilement envoyer et obtenir la réponse de la demande POST en utilisant "Demande - Client HTTP simplifié" et Javascript Promise.

var request = require('request');

function getData() {
    var options = {
        url: 'https://example.com',
        headers: {
            'Content-Type': 'application/json'
        }
    };

    return new Promise(function (resolve, reject) {
        var responseData;
        var req = request.post(options, (err, res, body) => {
            if (err) {
                console.log(err);
                reject(err);
            } else {
                console.log("Responce Data", JSON.parse(body));
                responseData = body;
                resolve(responseData);
            }
        });
    });
}
Kaveesha Baddage
la source
0

Vous devez utiliser bodyParser () si vous souhaitez que les données du formulaire soient disponibles dans req.body. body-parser analyse votre demande et la convertit en un format à partir duquel vous pouvez facilement extraire les informations pertinentes dont vous pourriez avoir besoin.

Par exemple, supposons que vous ayez un formulaire d'inscription à votre frontend. Vous le remplissez et demandez au serveur de sauvegarder les détails quelque part.

Extraire le nom d'utilisateur et le mot de passe de votre demande est aussi simple que ci-dessous si vous utilisez l'analyseur corporel.

…………………………………………………….

var loginDetails = {

username : request.body.username,

password : request.body.password

};
Rubin bhandari
la source
0

ONE LINER sans MIDDLEWARE
Si vous publiez les données suivantes,
'name':'ABC'
vous pouvez ensuite les analyser en utilisant la ligne suivante,

require('url').parse(req.url, true).query.name
Hardik Trivedi
la source