Comment extraire les données POST dans le noeud.js?
comment extraire les données du formulaire ( form[method="post"]
) et télécharger les fichiers envoyés à partir de la méthode HTTP POST
dans le noeud .js ?
j'ai lu la documentation, cherché et rien trouvé.
function (request, response) {
//request.post????
}
y a-t-il une bibliothèque ou un hack?
23 réponses
Si vous utilisez Express (haute performance, haute de classe de développement web pour le Nœud.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);
});
mis à jour le 1/juin/2016:
La méthodeci-dessus est dépréciée utiliser 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)
});
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 champ input
avec le nom age
, vous pouvez y accéder en utilisant la variable post
:
console.log(post.age);
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
});
}
}
voici un emballage sans cadre très simple basé sur les autres réponses et articles affiché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);
ce sera plus propre si vous encodez vos données en JSON , puis envoyez-les au noeud.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));
});
}
}
beaucoup de réponses ici ne sont plus de bonnes pratiques ou n'expliquent plus rien, c'est pourquoi j'écris ceci.
quand le rappel de http.createServer est appelé, c'est quand le serveur a effectivement 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 attendre. L'objet de requête http (un http.IncomingMessage instance) est en fait un lisible flux . Dans les flux lisibles chaque fois qu'un morceau de données arrive, un data
l'événement est émis (en supposant que vous avez enregistré un rappel) et lorsque tous les morceaux sont arrivés un événement end
est émis. Voici un exemple sur la façon dont vous écoutez les é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 n'avez pas affaire à des données binaires et que vous devez travailler avec des chaînes de caractères, je vous suggère d'utiliser la requête .la méthode de setEncoding qui provoque le flux émet des chaînes interprétées avec le codage donné et gère correctement les caractères à plusieurs octets.
Maintenant vous n'êtes probablement pas intéressé par chaque morceau par lui-même, donc dans ce cas probablement vous voulez amortir 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 tampon.le concat est utilisé, qui concaténate simplement tous les tampons et renvoie un grand tampon. Vous pouvez également utiliser le module 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 des formulaires HTML POST submission with no files ou handing jQuery ajax appels avec le type de contenu par défaut, alors le type de contenu est application/x-www-form-urlencoded
avec uft-8
encodage. Vous pouvez utiliser l' 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.analyser .
si vous avez affaire à des fichiers ou manipulez le type de contenu multipart, alors dans ce cas, vous devez utiliser quelque chose comme formidable qui élimine toute la douleur de traiter avec elle. Avoir un coup d'oeil à cette autre réponse de la mienne où j'ai posté des liens utiles et des modules pour le contenu multipart.
si vous ne voulez pas analyser le contenu mais plutôt le passer à un autre endroit, par exemple l'Envoyer à une autre requête http comme les données ou le sauvegarder dans un fichier, je suggère piping it plutôt que de le tamponner, car il sera moins de code, gère mieux la pression arrière, il prendra moins de mémoire et dans certains cas plus rapide.
donc si vous voulez sauvegarder le contenu dans un fichier:
http.createServer((request, response) => {
request.pipe(fs.createWriteStream('./request'));
}).listen(8080)
comme d'autres réponses ont noté gardez à l'esprit que les clients malveillants pourraient vous envoyer une énorme quantité de données pour planter votre application ou de remplir votre mémoire afin de protéger que vous assurez-vous drop requêtes qui émettent des données passer 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 flux-mètre qui peut interrompre l' 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)), ...);
aussi essayer d'utiliser les modules npm plutôt mettre en œuvre sur votre propre car ils seront probablement mieux gérer les cas de bord. Pour express, je suggère d'utiliser body-parser . Pour koa, il y a un module similaire .
si vous n'utilisez pas de framework, corps est assez bon.
pour tous ceux qui se demandent comment faire cette tâche triviale sans installer un framework web, j'ai réussi à le plop ensemble. La production est à peine prête, mais elle 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);
})
}
}
vous pouvez utiliser body-parser
, le noeud.js corps de l'analyse de middleware.
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é ici
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
});
, 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);
// ...
});
si vous ne voulez pas fractionner vos données avec le rappel data
, vous pouvez toujours utiliser le rappel readable
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 reçue, mais dès que vous avez terminé votre réponse, la demande sera ramassée, donc cela ne devrait pas être un problème.
une approche avancée serait de vérifier d'abord la taille du corps, si vous avez peur de corps énormes.
Il y a plusieurs façons de le faire. Cependant, le moyen le plus rapide que je connaisse est d'utiliser L'Express.bibliothèque 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);
qui peut fonctionner pour les cordes, mais je changerais bodyParser.urlencoded à bodyParser.json à la place 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 /
vous devez recevoir les données POST
en morceaux en utilisant request.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 thejh suggéré .
si vous utilisez Express.js , avant de pouvoir accéder à la req.body, vous devez ajouter middleware bodyParser:
app.use(express.bodyParser());
alors vous pouvez demander
req.body.user
et si vous ne voulez pas utiliser tout le cadre comme Express, mais vous avez aussi besoin de différents types de formulaires, y compris les téléchargements, alors formaline peut être un bon choix.
il est répertorié dans noeud.modules js
- Installer
'body-parser'
de mnp. - puis ouvrir
app.ts
-- > écrire - >var bodyParser = require('body-parser');
- alors vous devez écrire
app.use(bodyParser.json())
dansapp.ts
module -
n'oubliez pas d'inclure
app.use(bodyParser.json())
dans le haut ou avant toute déclaration de module. Ex:app.use(bodyParser.json()) app.use('/user',user);
-
puis utiliser
var postdata = req.body;
pour ceux qui utilisent raw binaire post upload sans encodage au-dessus, 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!");
});
});
limite la taille du poteau éviter d'inonder votre application de noeud. Il ya un grand raw-body module, adapté à la fois pour express et connect, qui peut vous aider à limiter la demande par la taille et la longueur.
j'ai trouvé une vidéo qui explique comment le faire: https://www.youtube.com/watch?v=nuw48-u3Yrg
il utilise le module par défaut" http "avec les modules" querystring "et" stringbuilder". L'application prend deux nombres (en utilisant deux boîtes de texte) à partir d'une page web et à soumettre, retourne la somme de ces deux (avec la persistance des valeurs dans les boîtes de texte). C'est le meilleur exemple que j'ai pu trouver nulle part 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);
S'il s'agit d'un téléchargement de fichier, le navigateur l'envoie habituellement sous la forme d'un contenu de type "multipart/form-data"
.
Vous pouvez l'utiliser dans de tels cas
var multipart = require('multipart');
multipart.parse(req)
sur les champs de formulaire comme ceux-ci
<input type="text" name="user[name]" value="MyName">
<input type="text" name="user[email]" value="myemail@somewherefarfar.com">
certaines des réponses ci-dessus échoueront parce qu'elles ne supportent que des données plates.
pour l'instant j'utilise la réponse Casey Chu mais avec le " qs " au lieu du module" querystring". C'est le module "corps-analyseur" utilise ainsi. Donc, si vous voulez de données imbriquées, vous devez installer qs.
npm install qs --save
remplacer 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.
});
}
}
si vous préférez utiliser le noeud pur.js alors vous pourriez extraire des données POST comme il est montré 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}`);
});
vous pouvez extraire le paramètre post sans utiliser express.
1: nmp install multiparty
2: importer multipartite . comme var 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 la forme HTML est.
<form method=POST enctype=multipart/form-data>
<input type=text name=userfile1><br>
<input type=submit>
</form>
j'espère que ça va marcher pour vous. Grâce.