Bagaimana cara mengambil parameter permintaan POST?

768

Ini formulir sederhana saya:

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

Ini kode Express.js /Node.js saya :

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

Saya mencoba sReq.query.emailatau sReq.query['email']atau sReq.params['email'], dll. Tidak ada yang berfungsi. Mereka semua kembali undefined.

Ketika saya berganti ke Panggilan, itu berfungsi, jadi .. ada ide?

murvinlai
sumber
33
KEAMANAN : semua orang yang menggunakan bodyParser()dari jawaban di sini juga harus membaca jawaban @SeanLynch di bawah ini
FelipeAls
Gunakan modul body-parser . Berikut adalah beberapa contoh penggunaan bermanfaat untuk pengurai tubuh
drorw

Jawaban:

1251

Segala sesuatu telah berubah sekali lagi mulai Express 4.16.0 , sekarang Anda dapat menggunakan express.json()dan express.urlencoded()seperti di Express 3.0 .

Ini berbeda mulai Express 4.0 hingga 4.15 :

$ npm install --save body-parser

lalu:

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

Sisanya seperti di Express 3.0 :

Pertama, Anda perlu menambahkan beberapa middleware untuk mem-parsing data postingan tubuh.

Tambahkan satu atau kedua baris kode berikut:

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

Kemudian, di handler Anda, gunakan req.bodyobjek:

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

Perhatikan bahwa penggunaan express.bodyParser()tidak dianjurkan.

app.use(express.bodyParser());

... setara dengan:

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

Masalah keamanan ada bersama express.multipart(), dan karena itu lebih baik menambahkan secara eksplisit untuk jenis pengkodean spesifik yang Anda butuhkan. Jika Anda memerlukan pengkodean multi bagian (untuk mendukung mengunggah file misalnya) maka Anda harus membaca ini .

Drew Noakes
sumber
76
Jika jawaban ini tidak berfungsi dengan baik, pastikan Anda memiliki content-typeset tajuk, misalnya:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe
6
apa perbedaan antara memposting formulir dengan pasangan nama / nilai dan memposting tubuh JSON? Apakah mereka berdua muncul di req.body?
chovy
7
@ Chovy Ya, benar. bodyParserabstrak JSON, URL-encoded, dan multipart data ke req.bodyobjek.
Kristján
7
Kode ini memberi saya kesalahan karena middleware tidak lagi dibundel dengan Express; Anda harus menggunakan body-parser: github.com/senchalabs/connect#middleware
araneae
11
Untuk membaca json menggunakan Express 4, hanya app.use(require('body-parser').json())baris yang cukup. Dan kemudian Anda dapat membaca data json dari objek tubuh permintaan Anda, yaitu req.bodydari dalam definisi rute.
Martin Carel
90

Masalah keamanan menggunakan express.bodyParser ()

Sementara semua jawaban yang lain saat ini merekomendasikan menggunakan express.bodyParser()middleware, ini sebenarnya adalah sebuah bungkus sekitar express.json(), express.urlencoded()dan express.multipart()middlewares ( http://expressjs.com/api.html#bodyParser ). Penguraian badan permintaan formulir dilakukan oleh express.urlencoded()middleware dan hanya itu yang Anda perlukan untuk mengekspos data formulir Anda pada req.bodyobjek.

Karena masalah keamanan dengan bagaimana express.multipart()/ connect.multipart()membuat file sementara untuk semua file yang diunggah (dan bukan sampah yang dikumpulkan), sekarang disarankan untuk tidak menggunakan express.bodyParser()pembungkus tetapi gunakan hanya middlewares yang Anda butuhkan.

Catatan: connect.bodyParser()akan segera diperbarui untuk hanya menyertakan urlencodeddan jsonketika Connect 3.0 dirilis (yang diperluas Express).


Jadi singkatnya, bukannya ...

app.use(express.bodyParser());

...kamu harus menggunakan

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

dan jika / ketika Anda perlu menangani formulir multi-bagian (unggah file), gunakan perpustakaan pihak ketiga atau middleware seperti multi-partai, busboy, pemain dadu, dll.

Sean Lynch
sumber
Menambahkan komentar di bawah pertanyaan sehingga lebih banyak orang melihat kekhawatiran dan saran Anda. Apakah solusi lain yang dirinci dalam posting blog Andrew Kelley (masih) relevan menurut pendapat Anda? (hanya meminta yang lain, kebutuhan saya murni untuk alat internal ^^)
FelipeAls
@FelipeAls - Ya, dan saya bermaksud merujuk posting Andrew juga. Setiap saran itu (dengan mempertimbangkan kejatuhan masing-masing) adalah relevan.
Sean Lynch
Selain itu, setelah Connect 3.0 dirilis tanpa termasuk multipart()sebagai bagian dari bodyParser(), bodyParser()menjadi "aman" lagi, tetapi Anda harus secara eksplisit mengaktifkan dukungan multi bagian menggunakan perpustakaan pihak ketiga.
Sean Lynch
84

Catatan : jawaban ini untuk Express 2. Lihat di sini untuk Express 3.

Jika Anda menggunakan connect / express, Anda harus menggunakan middleware bodyParser : Ini dijelaskan dalam panduan 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
});

Ini versi asli yang hanya terhubung:

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

Querystring dan body diuraikan menggunakan penanganan parameter Rails-style ( qs) daripada pustaka tingkat rendahquerystring . Dalam rangka untuk mengurai parameter diulang dengan qs, parameter harus memiliki kurung: name[]=val1&name[]=val2. Ini juga mendukung peta bersarang. Selain mem-parsing pengiriman form HTML, bodyParser dapat mem-parsing permintaan JSON secara otomatis.

Sunting : Saya membaca di express.js dan mengubah jawaban saya agar lebih alami bagi pengguna Express.

yonran
sumber
Hmm baiklah. saya mencoba bodyParser (). doc mengatakan saya bisa mendapatkannya dari req.query () tetapi saya tidak mendapatkan apa-apa. itu sangat aneh. Saya tidak punya masalah dengan Get tho.
murvinlai
3
Tidak, req.query HANYA adalah GET params. Anda mendapatkan data POST melalui req.body. Fungsi req.params () termasuk keduanya.
yonran
Klik nyasar ke bawah memilih jawaban ini tanpa sengaja tanpa saya perhatikan! Sekarang StackOverflow tidak akan membiarkan saya mengubahnya. Esp. frustasi karena ini membantu ... Saya memilih jawaban Anda yang lain yang baik yang saya tidak secara eksplisit mencari untuk menebusnya. :)
HostileFork bilang jangan percaya SE
33

Ini akan melakukannya jika Anda ingin membangun kueri yang diposting tanpa middleware:

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

});

Itu akan mengirim ini ke browser

email=emailval&password1=pass1val&password2=pass2val

Mungkin lebih baik menggunakan middleware sehingga Anda tidak perlu menulis ini berulang-ulang di setiap rute.

med116
sumber
3
sooo .... berguna, bagi mereka yang tidak mau bergantung pada perpustakaan yang cepat atau lambat akan ditinggalkan
Daniel
Anda dapat dengan mudah membangun middleware Anda sendiri
maioman
Ini adalah jawaban yang bagus tetapi mengapa ada teks tambahan "---------------------------- 359856253150893337905494 Content-Disposition: form-data; name = "fullName" Ram ---------------------------- 359856253150893337905494-- "Saya tidak ingin nomor itu.
Nawaraj
25

Catatan untuk pengguna Express 4:

Jika Anda mencoba dan memasukkan app.use(express.bodyParser());aplikasi Anda, Anda akan mendapatkan kesalahan berikut ketika Anda mencoba memulai server Express Anda:

Kesalahan: Sebagian besar middleware (seperti bodyParser) tidak lagi dibundel dengan Express dan harus diinstal secara terpisah. Silakan lihat https://github.com/senchalabs/connect#middleware .

Anda harus menginstal paket body-parsersecara terpisah dari npm , kemudian menggunakan sesuatu seperti berikut (contoh diambil dari halaman 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
sumber
Terima kasih banyak atas informasi ini. Sedang mencabut rambutku mencoba berurusan dengan cara baru menggunakan bodyParser! Ini adalah terobosan besar - sangat menghargai
Tommy
1
heplp: body-parser bodyparser yang sudah tidak digunakan lagi: gunakan individual json / urlencoded middlewares
Mohammad Faizan khan
19

Diberikan beberapa bentuk:

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

Menggunakan express

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

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

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

Keluaran:

{"name":"x","description":"x"}
req.param.name x
David
sumber
6
tidak bekerja untuk saya. perlu menggunakan app.use (express.bodyParser ());
cawecoy
@cawecoy benar-benar sama di sini tetapi express.bodyParser () tidak bekerja dengan baik bagi saya itu sudah tidak berlaku lagi
Mohammad Faizan khan
@MohammadFaizankhan itu adalah karya eksperimental, saya tidak menggunakan express lagi, tidak bisa membantu sekarang. Google untuk fungsi serupa dengan express.bodyParser (). semoga beruntung!
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);
});

Paling depan:

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
});
danau
sumber
15
app.use(express.bodyParser());

Kemudian untuk app.postpermintaan Anda bisa mendapatkan nilai posting melalui req.body.{post request variable}.

Chinthaka Senanayaka
sumber
variabel permintaan pos Anda di sini, apakah itu id bidang masukan yang dipertanyakan atau seluruh formulir atau apa?
Eogcloud
2
express.bodyParser () sudah usang. perbarui jawaban Anda
Mohammad Faizan khan
15

Pembaruan untuk Express 4.4.1

Middleware dari yang berikut ini dihapus dari Express.

  • bodyParser
  • json
  • urlencoded
  • multi bagian

Ketika Anda menggunakan middleware langsung seperti yang Anda lakukan di express 3.0. Anda akan mendapatkan kesalahan berikut:

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


Untuk memanfaatkan middleware tersebut, sekarang Anda harus melakukan npm untuk setiap middleware secara terpisah.

Karena bodyParser ditandai sebagai usang, jadi saya merekomendasikan cara berikut menggunakan json, urlencode dan multipart parser seperti tangguh, hubungkan-multipartai. (Multipart middleware juga tidak digunakan lagi).

Juga ingat, cukup mendefinisikan urlencode + json, formulir data tidak akan diuraikan dan req.body akan tidak terdefinisi. Anda perlu mendefinisikan middleware menangani permintaan multi-bagian.

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
sumber
Saya kira ini adalah pembaruan fitur yang sangat buruk
Mohammad Faizan khan
hanya demi parse tubuh saya harus melakukan banyak kode. apa hacknya
Mohammad Faizan khan
1
Saya harus menambahkan ".middleware ()" untuk meminta ('json-middleware') agar ini berfungsi.
DustinB
8

Untuk Express 4.1 ke atas

Karena sebagian besar jawaban digunakan untuk Express, bodyParser, sambungkan; di mana banyak bagian sudah usang. Ada cara aman untuk mengirim benda pos multi bagian dengan mudah.

Multer dapat digunakan sebagai pengganti connect.multipart ().

Untuk menginstal paket

$ npm install multer

Muat di aplikasi Anda:

var multer = require('multer');

Dan kemudian, tambahkan di tumpukan middleware bersama dengan bentuk middleware parsing lainnya.

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

connect.json () menangani aplikasi / json

connect.urlencoded () menangani aplikasi / x-www-form-urlencoded

multer () menangani multipart / formulir-data

Lalit Umbarkar
sumber
8

Saya sedang mencari masalah yang tepat ini. Saya mengikuti semua saran di atas tetapi req.body masih mengembalikan objek kosong {}. Dalam kasus saya, itu adalah sesuatu yang sederhana seperti html yang salah.

Di html formulir Anda, pastikan Anda menggunakan 'name'atribut di tag input Anda, bukan hanya 'id'. Kalau tidak, tidak ada yang diuraikan.

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

Kesalahan bodoh saya adalah keuntungan Anda.

cwingrav
sumber
Masalah yang sama disini. Tapi saya menggunakan atribut nama sejak awal. Mari kita lihat apa masalahnya.
Saif Al Falah
6

Anda tidak harus menggunakan app.use (express.bodyParser ()) . BodyParser adalah gabungan dari json + urlencoded + mulitpart. Anda tidak boleh menggunakan ini karena multipart akan dihapus di connect 3.0.

Untuk mengatasinya, Anda dapat melakukan ini:

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

Sangat penting untuk mengetahui bahwa app.use (app.router) harus digunakan setelah json dan urlencoded, jika tidak app !

HenioJR
sumber
4

Permintaan streaming berfungsi untuk saya

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

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});
zeah
sumber
1
Lebih baik daripada melakukan postdata.split("&")akan memuat modul inti querystring = require('querystring')dan kemudian menguraikan Anda postdatadengan querystring.parse(postdata);
John Slegers
4

Saya dapat menemukan semua parameter dengan menggunakan kode berikut untuk permintaan POST dan 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));
})
ARUNBALAN NV
sumber
apakah Anda keberatan memperbarui jawaban dengan versi ekspres Anda?
lfender6445
3

Ditulis pada versi Express 4.16

Di dalam fungsi router Anda dapat menggunakan req.bodyproperti untuk mengakses variabel post. Misalnya jika ini adalah POSTrute formulir Anda, itu akan mengirim kembali apa yang Anda masukkan:

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

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

PS untuk mereka yang terbiasa dengan PHP: Untuk mengakses $_GETvariabel PHP yang kami gunakan req.querydan untuk mengakses $_POSTvariabel PHP yang kami gunakan req.bodydi Node.js.

Logan
sumber
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");
})
seme
sumber
1

Parameter Post dapat diambil sebagai berikut:

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');
}
Hamidhan
sumber
2
apakah kamu sadar ini tidak akan berhasil? paramdigunakan untuk MENDAPATKAN permintaan .. bukan POST dan contoh Anda kurang detail, sangat membingungkan bagi pendatang baru. Dan di atas itu request.paramsebenarnya sudah usang, jadi contoh Anda salah pada banyak tingkatan.
vdegenne
0

Anda menggunakan req.query.postdengan metode yang salah req.query.postbekerja method=get, method=postbekerja dengan body-parser .

Coba saja ini dengan mengubah pos untuk mendapatkan :

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

Dan dalam kode kilat gunakan 'app.get'

sagar saini
sumber
0

Gunakan paket -fileupload ekspres :

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');
});
Chirag
sumber