จะดึงพารามิเตอร์ข้อความค้นหา 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พวกเขากลับมาทั้งหมด

เมื่อฉันเปลี่ยนเป็นรับสายมันจะทำงานได้ดังนั้น .. ความคิดใด ๆ


33
ความปลอดภัย : ทุกคนที่ใช้bodyParser()คำตอบที่นี่ควรอ่านคำตอบของ
@SeanLynch

คำตอบ:


1251

สิ่งที่มีการเปลี่ยนแปลงอีกครั้งเริ่มต้นเอ็กซ์เพรส 4.16.0ตอนนี้คุณสามารถใช้express.json()และexpress.urlencoded()เช่นเดียวกับในเอ็กซ์เพรส 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()จึงควรเพิ่มการสนับสนุนสำหรับประเภทการเข้ารหัสเฉพาะที่คุณต้องการอย่างชัดเจน ถ้าคุณทำเช่นการเข้ารหัส 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วัตถุ
Kristján

7
รหัสนี้ให้ข้อผิดพลาดแก่ฉันเนื่องจากมิดเดิลแวร์ไม่ได้รวมอยู่กับ Express อีกต่อไป คุณจะต้องใช้โปรแกรมแยกวิเคราะห์ร่างกาย: github.com/senchalabs/connect#middleware
araneae

11
สำหรับการอ่าน json โดยใช้ Express 4 มีเพียงapp.use(require('body-parser').json())บรรทัดเท่านั้น จากนั้นคุณสามารถอ่านข้อมูล json จากวัตถุร่างกายของคำขอของคุณเช่นreq.bodyจากภายในคำจำกัดความของเส้นทาง
Martin Carel

90

ความกังวลด้านความปลอดภัยโดยใช้ express.bodyParser ()

ในขณะที่ทุกคำตอบอื่น ๆ ในขณะนี้ขอแนะนำให้ใช้express.bodyParser()มิดเดิลแวร์นี้เป็นจริงเสื้อคลุมรอบexpress.json(), express.urlencoded()และexpress.multipart()middlewares ( http://expressjs.com/api.html#bodyParser ) การแยกวิเคราะห์เนื้อหาคำร้องขอทำโดยexpress.urlencoded()มิดเดิลแวร์และเป็นสิ่งที่คุณต้องเปิดเผยข้อมูลแบบฟอร์มของคุณบนreq.bodyวัตถุ

เนื่องจากข้อกังวลด้านความปลอดภัยเกี่ยวกับวิธีexpress.multipart()/ connect.multipart()สร้างไฟล์ชั่วคราวสำหรับไฟล์ที่อัปโหลดทั้งหมด (และไม่ได้เก็บรวบรวมขยะ) ตอนนี้ขอแนะนำไม่ให้ใช้express.bodyParser()wrapper แต่ใช้มิดเดิ้ลที่คุณต้องการแทน

หมายเหตุ: connect.bodyParser()เร็ว ๆ นี้จะได้รับการอัปเดตเพื่อรวมurlencodedและjsonเมื่อมีการเปิดตัวการเชื่อมต่อ 3.0 (ซึ่งขยายอย่างรวดเร็ว)


ดังนั้นในระยะสั้นแทน ...

app.use(express.bodyParser());

... คุณควรใช้

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

และหาก / เมื่อคุณต้องการจัดการรูปแบบหลายส่วน (อัปโหลดไฟล์) ให้ใช้ห้องสมุดบุคคลที่สามหรือมิดเดิลแวร์เช่นหลายส่วน busboy, dicer ฯลฯ


เพิ่มความคิดเห็นด้านล่างคำถามเพื่อให้ผู้คนเห็นความกังวลและคำแนะนำของคุณมากขึ้น โซลูชันอื่น ๆ จะมีรายละเอียดในAndrew Kelley บล็อกโพสต์ (ยัง) เกี่ยวข้องในความคิดเห็นของคุณหรือไม่ (แค่ขอให้คนอื่น ๆ ความต้องการของฉันนั้นล้วน แต่เป็นเครื่องมือภายในเท่านั้น ^^)
FelipeAls

@FelipeAls - ใช่แล้วและฉันต้องการอ้างอิงโพสต์ของ Andrew เช่นกัน ข้อเสนอแนะใด ๆ เหล่านั้น (โดยคำนึงถึงความหายนะของแต่ละคน) มีความเกี่ยวข้อง
Sean Lynch

นอกจากนี้เมื่อเชื่อมต่อ 3.0 ถูกปล่อยออกมาโดยไม่รวมmultipart()เป็นส่วนหนึ่งของbodyParser(), bodyParser()กลายเป็น "ปลอดภัย" อีกครั้ง แต่คุณจะต้องเปิดใช้งานอย่างชัดเจนสนับสนุน multipart ใช้ห้องสมุดของบุคคลที่สาม
Sean Lynch

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

ทั้ง querystring และ body ถูกวิเคราะห์โดยใช้การจัดการพารามิเตอร์สไตล์ Rails ( qs)แทนที่จะเป็นไลบรารี่ระดับต่ำ querystringเพื่อที่จะแยกพารามิเตอร์ซ้ำกับพารามิเตอร์ต้องมีวงเล็บ:qs name[]=val1&name[]=val2นอกจากนี้ยังรองรับแผนที่ที่ซ้อนกัน นอกเหนือจากการแยกวิเคราะห์การส่งแบบฟอร์ม HTML, bodyParser สามารถแยกวิเคราะห์คำขอ JSON โดยอัตโนมัติ

แก้ไข : ฉันอ่านข้อมูล express.js และแก้ไขคำตอบของฉันเพื่อให้ผู้ใช้ Express เป็นธรรมชาติมากขึ้น


อืมโอเค. ฉันลอง bodyParser () หมอบอกว่าฉันจะได้มันจาก req.query () แต่ฉันไม่ได้อะไรเลย มันแปลกมาก ฉันไม่มีปัญหากับ Get tho
murvinlai

3
ไม่ req.query เป็นเพียงพารามิเตอร์ GET เท่านั้น คุณได้รับข้อมูล POST ผ่าน req.body ฟังก์ชัน req.params () ประกอบด้วยทั้งสองอย่าง
yonran

คลิกที่เร่ร่อนลงคำตอบนี้โดยไม่ตั้งใจฉันไม่ได้สังเกตเห็น! ตอนนี้ 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 .... มีประโยชน์สำหรับผู้ที่ไม่ต้องการใช้ห้องสมุดที่จะเลิกใช้ไม่ช้าก็เร็ว
Daniel

คุณสามารถสร้างมิดเดิ้ลของคุณเองได้อย่างง่ายดาย
maioman

นี่เป็นคำตอบที่ดี แต่ทำไมจึงมีข้อความเพิ่มเติม "---------------------------- 359856253150893337905494 การจัดการเนื้อหา: form-data; name = "fullName" Ram ---------------------------- 359856253150893337905494-- "ฉันไม่ต้องการหมายเลขนั้น
Nawaraj

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: body-parser เลิกใช้ 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);
});

ส่วนหน้า:

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.postreq.body.{post request variable}


ตัวแปรคำขอโพสต์ของคุณที่นี่นั่นคือ id ของฟิลด์อินพุตที่เป็นปัญหาหรือทั้งแบบฟอร์มหรืออะไร
Eogcloud

2
express.bodyParser () เลิกใช้แล้ว อัปเดตคำตอบของคุณ
Mohammad Faizan khan

15

อัพเดทสำหรับ Express 4.4.1

Middleware ของสิ่งต่อไปนี้จะถูกลบออกจาก Express

  • bodyParser
  • JSON
  • urlencoded
  • multipart

เมื่อคุณใช้มิดเดิลแวร์โดยตรงเหมือนกับที่คุณทำใน express 3.0 คุณจะได้รับข้อผิดพลาดดังต่อไปนี้:

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


เพื่อที่จะใช้มิดเดิลแวร์เหล่านั้นตอนนี้คุณต้องทำnpmสำหรับมิดเดิลแวร์แต่ละอันแยกกัน

เนื่องจาก bodyParser ถูกทำเครื่องหมายว่าเลิกใช้แล้วดังนั้นฉันแนะนำวิธีต่อไปนี้โดยใช้ json, urlencode และ multipart parser เช่น formidable, connect-multiparty (มิดเดิลแวร์ Multipart ไม่รองรับเช่นกัน)

โปรดจำไว้ว่าเพียงแค่กำหนด urlencode + json ข้อมูลในแบบฟอร์มจะไม่ถูกแยกวิเคราะห์และ req.body จะไม่ถูกกำหนด คุณต้องกำหนดมิดเดิลแวร์จัดการคำขอ multipart

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

ฉันเดาว่านี่เป็นการอัปเดตคุณลักษณะที่ไม่ดีจริงๆ
Mohammad Faizan khan

เพียงเพื่อประโยชน์ในการแยกวิเคราะห์เนื้อหาฉันต้องทำโค้ดจำนวนมาก แฮ็คคืออะไร
Mohammad Faizan khan

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 ()จัดการ application / json

connect.urlencoded ()จัดการแอพพลิเคชั่น / 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}

ความโง่เขลาของฉันคือผลประโยชน์ของคุณ


ปัญหาเดียวกันที่นี่ แต่ฉันใช้แอตทริบิวต์ชื่อตั้งแต่เริ่มต้น มาดูกันว่าปัญหาคืออะไร
Saif Al Falah

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

เขียนที่ Express version 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นั้นเลิกใช้จริงดังนั้นตัวอย่างของคุณผิดในหลาย ๆ ระดับ
vdegenne

0

คุณกำลังใช้req.query.postด้วยวิธีการที่ไม่ถูกต้องreq.query.postทำงานร่วมกับmethod=get, method=postทำงานร่วมกับร่างกาย 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'


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');
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.