Як отримати параметри запиту 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, він працює, так що ... будь-яка ідея?


33
БЕЗПЕКА : усі, хто використовує bodyParser()відповіді тут, також повинні прочитати відповідь @SeanLynch нижче
FelipeAls

Відповіді:


1251

Речі змінилися ще раз , починаючи Експрес 4.16.0 , тепер ви можете використовувати express.json()і express.urlencoded()так само , як в Express 3.0 .

Це було різним, починаючи з експрес 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?
chovy

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 з об'єкта тіла вашого запиту, тобто 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

і якщо / коли вам потрібно обробляти багаточастинні форми (завантаження файлів), використовуйте сторонні бібліотеки або проміжні програми, такі як багатопартійність, busboy, dicer тощо.


Додайте коментар нижче питання, щоб більше людей бачили ваші проблеми та поради. Чи були б інші рішення, деталізовані в публікації блогу Ендрю Келлі, (досі) актуальними на вашу думку? (просто прошу інших, мої потреби суто внутрішні інструменти ^^)
FelipeAls

@FelipeAls - Так, і я мав на увазі також посилання Андрія. Будь-яка з цих пропозицій (з урахуванням недоліків кожної) є релевантною.
Шон Лінч

Крім того, після того, як Connect 3.0 буде випущений, не включаючи його multipart()як частину bodyParser(), знову bodyParser()стає "безпечним", але вам потрібно буде чітко включити підтримку багаточастин, використовуючи сторонні бібліотеки.
Шон Лінч

84

Примітка : ця відповідь призначена для Express 2. Дивіться тут для Express 3.

Якщо ви використовуєте підключення / експрес, ви повинні використовувати проміжне програмне забезпечення 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.


Хм добре. я спробую bodyParser (). doc каже, що я можу отримати його з req.query (), але я нічого не отримав. це дуже дивно. У мене немає проблем з Get tho.
murvinlai

3
Ні, req.query - ТІЛЬКИ ПОЛУЧИТИ парами. Ви отримуєте дані POST через req.body. Функція req.params () включає їх обидва.
йонран

Бродячий клацання сприйняв цю відповідь випадково, не помічаючи мене! Тепер StackOverflow не дозволить мені це змінити. Esp розчарування, оскільки це було корисно ... Я підтримав ще одну вашу добру відповідь, яку я не шукав явно, щоб компенсувати це. :)
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

Можливо, краще використовувати посереднє програмне забезпечення, хоча вам не доведеться писати це знову і знову в кожному маршруті.


3
sooo .... зручно, для тих, хто не хоче покладатися на бібліотеку, яка рано чи пізно буде застаріла
Даніель

ви могли легко створити власне проміжне програмне забезпечення
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();
})

Дуже дякую за цю інформацію. Витягував волосся, намагаючись боротися з новим способом використання bodyParser! Це був великий прорив - дуже вдячний
Томмі

1
heplp: устарений тіло-аналізатор bodyParser: використовуйте індивідуальні середні вироби json / urlencoded
Mohammad Faizan khan

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 () працює не так добре, як для мене це застаріло
Mohammad Faizan khan

@MohammadFaizankhan це була експериментальна робота, я більше не використовую експрес, зараз не можу допомогти. Google це для аналогічних функцій для express.bodyParser (). удачі!
cawecoy

16

Бекенд:

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);
});

Frontend:

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
});

15
app.use(express.bodyParser());

Тоді за app.postзапитом ви можете отримувати значення пошти через req.body.{post request variable}.


Ваш змінний запит на публікацію тут - це ідентифікатор відповідного поля введення або вся форма чи що?
Eogcloud

2
express.bodyParser () застарілий. оновіть свою відповідь
Мохаммед Файзан хан

15

Оновлення для експресу 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. (Багатопосереднє програмне забезпечення також застаріло).

Також пам’ятайте, що тільки визначаючи 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);

Я здогадуюсь, це дійсно погана актуалізація функції
Мохаммед

просто заради розбору тіла я повинен робити багато коду. який хак
Мохаммед Файзан хан

1
Мені довелося додати ".middleware ()", щоб вимагати ("json-middleware"), щоб це працювало.
ДастінБ

8

Для Express 4.1 і вище

Оскільки більшість відповідей використовують для Express, bodyParser, connect; де багаточастинні застарілі. Існує безпечний спосіб легко надсилати поштові багаточастинні об'єкти.

Мультер можна використовувати як заміну для connect.multipart ().

Щоб встановити пакет

$ npm install multer

Завантажте його у своєму додатку:

var multer = require('multer');

А потім додайте його в стек середнього програмного забезпечення разом з іншими формами розбору проміжного програмного забезпечення.

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

connect.json () обробляє application / json

connect.urlencoded () обробляє додаток / x-www-form-urlencoded

multer () обробляє багаточастинні / форм-дані


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}

Моя ідіотська помилка - ваша користь.


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

6

Ви не повинні використовувати app.use (express.bodyParser ()) . BodyParser - це об'єднання json + urlencoded + mulitpart. Ви не повинні використовувати це, оскільки багатоповерхівка буде видалено в підключенні 3.0.

Щоб вирішити це, ви можете зробити це:

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

Дуже важливо знати, що app.use (app.router) слід використовувати після json та urlencoded, інакше це не працює!


4

Запит потокової передачі працював для мене

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

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});

1
Краще , ніж робити postdata.split("&")було б завантажити модуль ядра , querystring = require('querystring')а потім розібрати ваш postdataз querystring.parse(postdata);
Джон Slegers

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));
})

Ви не хочете оновлювати відповідь своєю версією Express?
lfender6445

3

Написано в Експрес-версії 4.16

Всередині функції маршрутизатора ви можете використовувати req.bodyвластивість для доступу до змінної публікації. Наприклад, якщо це 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');
}

1
ти розумієш, що це не вийде? paramвикористовується для GET-запитів .. не POST, і у вашому прикладі не вистачає деталей, що дуже заплутано для нових бажаючих. Крім того, request.paramце насправді застаріло, тож ваш приклад неправильний на багатьох рівнях.
вдегенне

0

Ви використовуєте req.query.postнеправильний метод, з яким req.query.postпрацює method=get, method=postпрацює з аналізатором тіла .

Просто спробуйте це, змінивши публікацію, щоб отримати :

<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"


0

Використовуйте пакет експрес-завантаження файлів :

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');
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.