Как получить параметры запроса POST?

768

Вот моя простая форма:

<form id="loginformA" action="userlogin" method="post">
    <div>
        <label for="email">Email: </label>
        <input type="text" id="email" name="email"></input>
    </div>
<input type="submit" value="Submit"></input>
</form>

Вот мой код Express.js /Node.js:

app.post('/userlogin', function(sReq, sRes){    
    var email = sReq.query.email.;   
}

Я пытался sReq.query.emailили sReq.query['email']или sReq.params['email']и т. Д. Ни один из них не работает. Они все возвращаются undefined.

Когда я переключаюсь на вызов Get, он работает, так что ... есть идеи?

murvinlai
источник
33
БЕЗОПАСНОСТЬ : каждый, кто использует bodyParser()ответы здесь, должен также прочитать ответ
@SeanLynch
Используйте модуль body-parser . Вот несколько полезных примеров использования body-parser
drorw

Ответы:

1251

Вещи изменились еще раз , начиная Экспресс 4.16.0 , теперь вы можете использовать express.json()и express.urlencoded()так же , как в Express 3.0 .

Это отличалось, начиная с Express 4.0 до 4.15 :

$ npm install --save body-parser

а потом:

var bodyParser = require('body-parser')
app.use( bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
})); 

Остальное как в Express 3.0 :

Во-первых, вам нужно добавить промежуточное программное обеспечение для анализа почтовых данных тела.

Добавьте одну или обе следующие строки кода:

app.use(express.json());       // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies

Затем в вашем обработчике используйте req.bodyобъект:

// assuming POST: name=foo&color=red            <-- URL encoding
//
// or       POST: {"name":"foo","color":"red"}  <-- JSON encoding

app.post('/test-page', function(req, res) {
    var name = req.body.name,
        color = req.body.color;
    // ...
});

Обратите внимание, что использование express.bodyParser()не рекомендуется.

app.use(express.bodyParser());

...эквивалентно:

app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());

Проблемы безопасности существуют express.multipart(), поэтому лучше явно добавить поддержку для конкретного типа (ов) кодирования, который вам требуется. Если вам нужно многокомпонентное кодирование (например, для поддержки загрузки файлов), вам следует прочитать это .

Дрю Ноакс
источник
76
Если этот ответ не работает правильно, убедитесь, что у вас установлен content-typeзаголовок, например:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe
6
В чем разница между публикацией формы с парами имя / значение и публикацией тела JSON? Они оба появляются в req.body?
Чови
7
@chovy Да, они делают. bodyParserабстрагирует JSON, URL-кодированные и составные данные в req.bodyобъект.
Кристьян
7
Этот код дал мне ошибки, так как промежуточное ПО больше не связано с Express; вам придется использовать body-parser: github.com/senchalabs/connect#middleware
araneae
11
Для чтения json с использованием Express 4 достаточно только app.use(require('body-parser').json())строки. И тогда вы можете прочитать данные json из объекта body вашего запроса, т. req.bodyЕ. Из определения маршрута.
Мартин Карел
90

Проблема безопасности с использованием express.bodyParser ()

В то время как все остальные ответы в настоящее время рекомендуется использовать express.bodyParser()промежуточное программное обеспечение , это на самом деле обертка вокруг express.json(), express.urlencoded()и express.multipart()промежуточное программное ( http://expressjs.com/api.html#bodyParser ). Разбор тела запроса формы выполняется express.urlencoded()промежуточным программным обеспечением, и это все, что вам нужно для предоставления данных формы на req.bodyобъекте.

Из-за проблем безопасности, связанных с тем, как express.multipart()/ connect.multipart()создает временные файлы для всех загруженных файлов (и они не являются сборщиком мусора), теперь рекомендуется не использовать express.bodyParser()оболочку, а вместо этого использовать только то промежуточное программное обеспечение, которое вам необходимо.

Примечание: connect.bodyParser()скоро будет обновлено, чтобы включить urlencodedи только jsonкогда выйдет Connect 3.0 (который расширяет Express).


Короче, вместо ...

app.use(express.bodyParser());

... вы должны использовать

app.use(express.urlencoded());
app.use(express.json());      // if needed

и если / когда вам нужно обрабатывать многочастные формы (загрузка файлов), используйте стороннюю библиотеку или промежуточное ПО, такое как multiparty, busboy, dicer и т. д.

Шон Линч
источник
Добавлен комментарий ниже вопроса, чтобы больше людей видели ваши проблемы и советы. Будут ли другие решения, подробно описанные в сообщении Эндрю Келли (все еще), актуальны, на ваш взгляд? (просто спрашиваю о других, мои нужды исключительно для внутренних инструментов ^^)
FelipeAls
@FelipeAls - Да, и я хотел сослаться на пост Эндрю. Любые из этих предложений (принимая во внимание недостатки каждого) актуальны.
Шон Линч
Кроме того, после того, как Connect 3.0 выпущен без включения в multipart()качестве части bodyParser(), он bodyParser()снова становится «безопасным», но вам необходимо явно включить поддержку нескольких компонентов с помощью сторонней библиотеки.
Шон Линч
84

Примечание : этот ответ для Express 2. Смотрите здесь для Express 3.

Если вы используете connect / express, вам следует использовать промежуточное ПО bodyParser : оно описано в руководстве по Expressjs .

// example using express.js:
var express = require('express')
  , app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res){
  var email = req.param('email', null);  // second parameter is default
});

Вот оригинальная версия только для подключения:

// example using just connect
var connect = require('connect');
var url = require('url');
var qs = require('qs');
var server = connect(
  connect.bodyParser(),
  connect.router(function(app) {
    app.post('/userlogin', function(req, res) {
      // the bodyParser puts the parsed request in req.body.
      var parsedUrl = qs.parse(url.parse(req.url).query);
      var email = parsedUrl.email || req.body.email;;
    });
  })
);

И строка запроса, и тело анализируются с помощью обработки параметров в стиле Rails ( qs), а не низкоуровневой querystringбиблиотеки . Для того , чтобы разобрать повторяющиеся параметры с qs, параметр должен иметь скобки: name[]=val1&name[]=val2. Он также поддерживает вложенные карты. В дополнение к синтаксическому анализу представлений HTML-формы bodyParser может автоматически анализировать запросы JSON.

Изменить : я прочитал на express.js и изменил свой ответ, чтобы быть более естественным для пользователей Express.

yonran
источник
Хмм хорошо. я пробую bodyParser (). Док говорит, что я могу получить его из req.query (), но у меня ничего нет. это очень странно У меня нет проблем с Get Tho.
Мурвинлай
3
Нет, req.query - ТОЛЬКО ПОЛУЧЕННЫЕ параметры. Вы получаете данные POST через req.body. Функция req.params () включает их обоих.
Йонран
Случайный щелчок понизил этот ответ случайно, не заметив меня! Теперь StackOverflow не позволит мне изменить его. Особенно разочарование, поскольку это было полезно ... Я проголосовал за еще один из ваших хороших ответов, которые я явно не искал, чтобы восполнить это. :)
HostileFork говорит, что не доверяйте SE
33

Это будет сделано, если вы хотите создать отправленный запрос без промежуточного программного обеспечения:

app.post("/register/",function(req,res){
    var bodyStr = '';
    req.on("data",function(chunk){
        bodyStr += chunk.toString();
    });
    req.on("end",function(){
        res.send(bodyStr);
    });

});

Это отправит это в браузер

email=emailval&password1=pass1val&password2=pass2val

Вероятно, лучше использовать промежуточное ПО, так что вам не придется писать это снова и снова на каждом маршруте.

med116
источник
3
тааак .... удобно, для тех, кто не хочет полагаться на библиотеку, которая рано или поздно устареет
Даниэль
Вы могли бы легко создать свое собственное промежуточное программное обеспечение
maioman
Это отличный ответ, но почему есть дополнительный текст "---------------------------- 359856253150893337905494 Содержание-Расположение: форма-данные; имя = "fullName" Ram ---------------------------- 359856253150893337905494-- "Я не хочу этот номер.
Наварадж
25

Примечание для пользователей Express 4:

Если вы попытаетесь вставить app.use(express.bodyParser());свое приложение, вы получите следующую ошибку при попытке запустить сервер Express:

Ошибка: большая часть промежуточного программного обеспечения (например, bodyParser) больше не связана с Express и должна быть установлена ​​отдельно. Пожалуйста, смотрите https://github.com/senchalabs/connect#middleware .

Вам нужно будет установить пакет body-parserотдельно от npm , а затем использовать что-то вроде следующего (пример взят со страницы GitHub ):

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

var app = express();

app.use(bodyParser());

app.use(function (req, res, next) {
  console.log(req.body) // populated!
  next();
})
mplewis
источник
Большое спасибо за эту информацию. Вытаскивал мои волосы, пытаясь справиться с новым способом использования bodyParser! Это был большой прорыв - очень ценю
Томми
1
heplp: body-parser устарел bodyParser: используйте отдельные промежуточные программы json / urlencoded
Мохаммад Файзан-хан,
19

Учитывая некоторую форму:

<form action='/somepath' method='post'>
   <input type='text' name='name'></input>
</form>

Используя экспресс

app.post('/somepath', function(req, res) {

    console.log(JSON.stringify(req.body));

    console.log('req.body.name', req.body['name']);
});

Вывод:

{"name":"x","description":"x"}
req.param.name x
Дэвид
источник
6
не работал для меня. необходимо использовать app.use (express.bodyParser ());
cawecoy
@cawecoy абсолютно верно то же самое здесь, но express.bodyParser () не работает, а для меня это устарело
Мохаммад Файзан хан
@MohammadFaizankhan это была экспериментальная работа, я больше не пользовался экспрессом, сейчас не могу помочь. Гугл это для похожих функций express.bodyParser (). удачи!
cawecoy
16

Backend:

import express from 'express';
import bodyParser from 'body-parser';

const app = express();
app.use(bodyParser.json()); // add a middleware (so that express can parse request.body's json)

app.post('/api/courses', (request, response) => {
  response.json(request.body);
});

Внешний интерфейс:

fetch("/api/courses", {
  method: 'POST',
  body: JSON.stringify({ hi: 'hello' }), // convert Js object to a string
  headers: new Headers({ "Content-Type": "application/json" }) // add headers
});
lakesare
источник
15
app.use(express.bodyParser());

Тогда для app.postзапроса вы можете получить значения поста через req.body.{post request variable}.

Чинтхака Сенанаяка
источник
Ваша переменная почтового запроса здесь, это идентификатор рассматриваемого поля ввода или всей формы или как?
Eogcloud
2
express.bodyParser () устарела. обновите ваш ответ
Мохаммад Файзан хан
15

Обновление для Express 4.4.1

Промежуточное программное обеспечение следующего удалено из Express.

  • bodyParser
  • JSON
  • urlencoded
  • многочастному

Когда вы используете промежуточное ПО напрямую, как в Express 3.0. Вы получите следующую ошибку:

Error: Most middleware (like urlencoded) is no longer bundled with Express and 
must be installed separately.


Чтобы использовать это промежуточное ПО, теперь вам нужно выполнить npm для каждого промежуточного ПО отдельно.

Поскольку bodyParser помечен как устаревший, поэтому я рекомендую следующий способ с использованием json, urlencode и многочастного парсера, например, грозного, connect-multiparty. (Multipart middleware также не рекомендуется).

Также помните, что, просто определяя urlencode + json, данные формы не будут анализироваться, а req.body будет неопределенным. Вам нужно определить промежуточное программное обеспечение для обработки многочастного запроса.

var urlencode = require('urlencode');
var json = require('json-middleware');
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();

app.use(json);
app.use(urlencode);
app.use('/url/that/accepts/form-data', multipartMiddleware);
yeelan
источник
я думаю, что это действительно плохое обновление функции
Мохаммад Файзан хан
просто для разбора тела я должен сделать много кода. что за хак
Мухаммед Файзан хан
1
Мне пришлось добавить ".middleware ()", чтобы требовать ('json-middleware'), чтобы заставить это работать.
DustinB
8

Для Express 4.1 и выше

Так как большинство ответов используют для Express, bodyParser, connect; где multipart устарела. Существует безопасный способ легко отправлять многокомпонентные объекты.

Multer можно использовать в качестве замены для connect.multipart ().

Чтобы установить пакет

$ npm install multer

Загрузите его в свое приложение:

var multer = require('multer');

Затем добавьте его в стек промежуточного программного обеспечения вместе с другим промежуточным программным обеспечением для анализа форм.

app.use(express.json());
app.use(express.urlencoded());
app.use(multer({ dest: './uploads/' }));

connect.json () обрабатывает приложение / json

connect.urlencoded () обрабатывает application / x-www-form-urlencoded

multer () обрабатывает multipart / form-data

Лалит Умбаркар
источник
8

Я искал именно эту проблему. Я следовал всем советам выше, но req.body все еще возвращал пустой объект {}. В моем случае, это было что-то столь же простое, как HTML, который был неправильным.

В html вашей формы убедитесь, что вы используете 'name'атрибут в своих входных тегах, а не только 'id'. В противном случае ничего не анализируется.

<input id='foo' type='text' value='1'/>             // req = {}
<input id='foo' type='text' name='foo' value='1' /> // req = {foo:1}

Моя идиотская ошибка - твоя выгода.

cwingrav
источник
Та же проблема здесь. Но я использовал атрибут name с самого начала. Посмотрим, в чем проблема.
Саиф Аль Фалах
6

Вы не должны использовать app.use (express.bodyParser ()) . BodyParser - это объединение json + urlencoded + mulitpart. Вы не должны использовать это, потому что multipart будет удален в Connect 3.0.

Чтобы решить это, вы можете сделать это:

app.use(express.json());
app.use(express.urlencoded());

Очень важно знать, что app.use (app.router) следует использовать после json и urlencoded, иначе это не работает!

HenioJR
источник
4

Поток запросов работал на меня

req.on('end', function() {
    var paramstring = postdata.split("&");
});

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});
zeah
источник
1
Лучше , чем делать postdata.split("&")было бы загрузить модуль ядра , querystring = require('querystring')а затем разобрать ваш postdataс querystring.parse(postdata);
Джон Слегерс
4

Я мог бы найти все параметры, используя следующий код для запросов POST и GET .

var express = require('express');
var app = express();
const util = require('util');
app.post('/', function (req, res) {
    console.log("Got a POST request for the homepage");
    res.send(util.inspect(req.query,false,null));
})
АРУНБАЛАН Н.В.
источник
Вы не хотите обновить ответ своей версией экспресса?
lfender6445
3

Написано в Express версии 4.16

Внутри функции маршрутизатора вы можете использовать req.bodyсвойство для доступа к переменной post. Например, если бы это был POSTмаршрут вашей формы, он вернул бы то, что вы ввели:

function(req,res){
      res.send(req.body);

      //req.body.email would correspond with the HTML <input name="email"/>
}

PS для тех, кто знаком с PHP: для доступа к $_GETпеременной PHP мы используем req.queryи для доступа к $_POSTпеременной PHP мы используем req.bodyв Node.js.

логан
источник
1
var express        =         require("express");
var bodyParser     =         require("body-parser");
var app            =         express();

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

app.get('/',function(req,res){
  res.sendfile("index.html");
});
app.post('/login',function(req,res){
  var user_name=req.body.user;
  var password=req.body.password;
  console.log("User name = "+user_name+", password is "+password);
  res.end("yes");
});
app.listen(3000,function(){
  console.log("Started on PORT 3000");
})
сема
источник
1

Параметры сообщения могут быть получены следующим образом:

app.post('/api/v1/test',Testfunction);
http.createServer(app).listen(port, function(){
    console.log("Express server listening on port " + port)
});

function Testfunction(request,response,next) {
   console.log(request.param("val1"));
   response.send('HI');
}
HamidKhan
источник
2
ты понимаешь, что это не сработает? paramиспользуется для запросов GET .. не POST и в вашем примере отсутствуют детали, что очень запутанно для новичков. И вдобавок к этому request.paramна самом деле не рекомендуется, так что ваш пример неверен на многих уровнях.
августа
0

Вы используете req.query.postс неправильным методом req.query.postработает method=get, method=postработает с body-parser .

Просто попробуйте это, изменив сообщение, чтобы получить :

<form id="loginformA" action="userlogin" method="get">
<div>
    <label for="email">Email: </label>
    <input type="text" id="email" name="email"></input>
</div>
<input type="submit" value="Submit"></input>  
</form>

А в экспресс-коде используйте «app.get»

Sagar Saini
источник
0

Используйте пакет express-fileupload :

var app = require('express')();
var http = require('http').Server(app);
const fileUpload = require('express-fileupload')

app.use(fileUpload());

app.post('/', function(req, res) {
  var email = req.body.email;
  res.send('<h1>Email :</h1> '+email);
});

http.listen(3000, function(){
  console.log('Running Port:3000');
});
Чираг
источник