วิธีเข้าถึงพารามิเตอร์ GET หลังจาก“?” ใน Express


527

ฉันรู้วิธีรับ params สำหรับข้อความค้นหาเช่นนี้:

app.get('/sample/:id', routes.sample);

ในกรณีนี้ฉันสามารถใช้req.params.idรับพารามิเตอร์ (เช่น2ใน/sample/2)

อย่างไรก็ตามสำหรับ url like /sample/2?color=redฉันจะเข้าถึงตัวแปรได้colorอย่างไร

ฉันพยายามreq.params.colorแต่มันใช้งานไม่ได้

คำตอบ:


776

ดังนั้นหลังจากตรวจสอบการอ้างอิงด่วนฉันพบว่าreq.query.colorจะคืนค่าที่ฉันต้องการ

req.params อ้างถึงรายการที่มี ':' ใน URL และ req.query หมายถึงรายการที่เกี่ยวข้องกับ '?'

ตัวอย่าง:

GET /something?color1=red&color2=blue

จากนั้นในการจัดการด่วน:

app.get('/something', (req, res) => {
    req.query.color1 === 'red'  // true
    req.query.color2 === 'blue' // true
})

คุณช่วยบอกวิธีการตรวจสอบ "id" ได้ไหม
อานันท์ราชา

1
@AnandRaj: คุณหมายถึงอะไร: วิธีการตรวจสอบ "id"? คุณต้องการการตรวจสอบประเภทใด BTW คุณจะได้รับค่าของฟังก์ชั่นของคุณเช่นนี้:id var sampleId = req.params.id;
Jochem Schulenklopper

4
ใช้req.params.whateverในเวอร์ชันล่าสุด
adelriosantiago

3
ใจที่req.paramsแตกต่างจากreq.query! expressjs.com/en/api.html#req.params expressjs.com/en/api.html#req.query @adelriosantiago
caesarsol

81

ใช้ req.query เพื่อรับค่าในพารามิเตอร์สตริงแบบสอบถามในเส้นทาง โปรดดูreq.query พูดว่าถ้าอยู่ในเส้นทางhttp: // localhost: 3000 /? name = satyam ที่คุณต้องการรับค่าพารามิเตอร์ name ดังนั้นตัวจัดการเส้นทาง 'Get' ของคุณจะเป็นดังนี้: -

app.get('/', function(req, res){
    console.log(req.query.name);
    res.send('Response send to client::'+req.query.name);

});

บางทีข้อมูลเกี่ยวกับการสอบถามเพื่อรับคำตอบที่สมบูรณ์
Schuere

67

อัปเดต: req.param()เลิกใช้แล้วดังนั้นการเดินหน้าอย่าใช้คำตอบนี้


คำตอบของคุณเป็นวิธีที่ต้องการที่จะทำมัน แต่ฉันคิดว่าฉันต้องการชี้ให้เห็นว่าคุณสามารถเข้าถึง URL req.param(parameterName, defaultValue)นี้ยังโพสต์และพารามิเตอร์เส้นทางทั้งหมดที่มี

ในกรณีของคุณ:

var color = req.param('color');

จากคู่มือด่วน:

การค้นหาจะดำเนินการตามลำดับต่อไปนี้:

  • req.params
  • req.body
  • req.query

โปรดทราบว่าคำแนะนำจะระบุสิ่งต่อไปนี้:

การเข้าถึงโดยตรงไปยัง req.body, req.params และ req.query ควรได้รับการสนับสนุนเพื่อความชัดเจน - เว้นแต่คุณจะยอมรับการป้อนข้อมูลจากแต่ละวัตถุอย่างแท้จริง

อย่างไรก็ตามในทางปฏิบัติฉันพบว่าreq.param()มีความชัดเจนเพียงพอและทำให้การปรับโครงสร้างบางประเภทง่ายขึ้น


53

สตริงการค้นหาและพารามิเตอร์ต่างกัน

คุณต้องใช้ทั้งใน url การกำหนดเส้นทางเดียว

โปรดตรวจสอบตัวอย่างด้านล่างอาจมีประโยชน์สำหรับคุณ

app.get('/sample/:id', function(req, res) {

 var id = req.params.id; //or use req.param('id')

  ................

});

รับลิงก์เพื่อส่งเซ็กเมนต์ที่สองของคุณคือตัวอย่าง id ของคุณ: http: // localhost: port / sample / 123

หากคุณประสบปัญหาโปรดใช้ผ่านตัวแปรเป็นสตริงแบบสอบถามโดยใช้ '?' ผู้ประกอบการ

  app.get('/sample', function(req, res) {

     var id = req.query.id; 

      ................

    });

รับลิงค์ตัวอย่างเช่นนี้ของคุณ: http: // localhost: port / sample? id = 123

ทั้งในตัวอย่างเดียว

app.get('/sample/:id', function(req, res) {

 var id = req.params.id; //or use req.param('id')
 var id2 = req.query.id; 
  ................

});

รับตัวอย่างลิงก์: http: // localhost: port / sample / 123? id = 123


2
ขอบคุณคำตอบนี้มีประโยชน์มาก!
บรูโน่ทาวาเรส

44

คำตอบของ @ugugit ถูกต้อง req.param()เลิกใช้แล้ว คุณควรใช้req.params, หรือreq.queryreq.body

เพียง แต่จะทำให้มันชัดเจน:

req.paramsจะถูกเติมด้วยค่าเส้นทางเท่านั้น นั่นคือถ้าคุณมีเส้นทางเช่น/users/:idคุณสามารถเข้าถึงidทั้งในหรือreq.params.idreq.params['id']

req.queryและreq.bodyจะบรรจุด้วยparams ทั้งหมดโดยไม่คำนึงว่าอยู่ในเส้นทางหรือไม่ แน่นอนพารามิเตอร์ในสตริงการสืบค้นจะสามารถใช้ได้ในและพารามิเตอร์ในร่างกายที่โพสต์จะอยู่ในที่มีอยู่req.queryreq.body

ดังนั้นการตอบคำถามของคุณเนื่องจากcolorไม่ได้อยู่ในเส้นทางคุณควรจะสามารถใช้มันได้req.query.colorreq.query['color']หรือ


17

คู่มือด่วนบอกว่าคุณควรใช้req.queryเพื่อเข้าถึง QueryString

// Requesting /display/post?size=small
app.get('/display/post', function(req, res, next) {

  var isSmall = req.query.size === 'small'; // > true
  // ...

});

7
const express = require('express')
const bodyParser = require('body-parser')
const { usersNdJobs, userByJob, addUser , addUserToCompany } = require ('./db/db.js')

const app = express()
app.set('view engine', 'pug')
app.use(express.static('public'))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.get('/', (req, res) => {
  usersNdJobs()
    .then((users) => {
      res.render('users', { users })
    })
    .catch(console.error)
})

app.get('/api/company/users', (req, res) => {
  const companyname = req.query.companyName
  console.log(companyname)
  userByJob(companyname)
    .then((users) => {
      res.render('job', { users })
    }).catch(console.error)
})

app.post('/api/users/add', (req, res) => {
  const userName = req.body.userName
  const jobName = req.body.jobName
  console.log("user name = "+userName+", job name : "+jobName)
  addUser(userName, jobName)
    .then((result) => {
      res.status(200).json(result)
    })
    .catch((error) => {
      res.status(404).json({ 'message': error.toString() })
    })
})
app.post('/users/add', (request, response) => {
  const { userName, job } = request.body
  addTeam(userName, job)
  .then((user) => {
    response.status(200).json({
      "userName": user.name,
      "city": user.job
    })
  .catch((err) => {
    request.status(400).json({"message": err})
  })
})

app.post('/api/user/company/add', (req, res) => {
  const userName = req.body.userName
  const companyName = req.body.companyName
  console.log(userName, companyName)
  addUserToCompany(userName, companyName)
  .then((result) => {
    res.json(result)
  })
  .catch(console.error)
})

app.get('/api/company/user', (req, res) => {
 const companyname = req.query.companyName
 console.log(companyname)
 userByJob(companyname)
 .then((users) => {
   res.render('jobs', { users })
 })
})

app.listen(3000, () =>
  console.log('Example app listening on port 3000!')
)

7
ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือแบบ จำกัด และทันที คำอธิบายที่เหมาะสมมากจะเพิ่มมูลค่าในระยะยาวด้วยการแสดงเหตุผลนี้เป็นทางออกที่ดีในการแก้ไขปัญหาและจะทำให้มันมีประโยชน์มากขึ้นให้กับผู้อ่านในอนาคตกับอื่น ๆ คำถามที่คล้ายกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงข้อสมมติฐานที่คุณทำ
iBug

2

เทคนิคที่ดีที่ฉันเริ่มใช้กับแอพของฉันบน express คือการสร้างวัตถุที่ผสานการสืบค้น params และฟิลด์เนื้อหาของวัตถุคำขอของ express

//./express-data.js
const _ = require("lodash");

class ExpressData {

    /*
    * @param {Object} req - express request object
    */
    constructor (req) {

        //Merge all data passed by the client in the request
        this.props = _.merge(req.body, req.params, req.query);
     }

}

module.exports = ExpressData;

จากนั้นในส่วนควบคุมของคุณหรือที่ใดก็ตามที่อยู่ในขอบเขตของห่วงโซ่คำขอด่วนคุณสามารถใช้สิ่งต่อไปนี้:

//./some-controller.js

const ExpressData = require("./express-data.js");
const router = require("express").Router();


router.get("/:some_id", (req, res) => {

    let props = new ExpressData(req).props;

    //Given the request "/592363122?foo=bar&hello=world"
    //the below would log out 
    // {
    //   some_id: 592363122,
    //   foo: 'bar',
    //   hello: 'world'
    // }
    console.log(props);

    return res.json(props);
});

นี้จะทำให้มันมีความสุขและมีประโยชน์เพียงแค่ "เจาะ" ในทั้งหมดของ "ข้อมูลที่กำหนดเอง" ผู้ใช้อาจจะส่งขึ้นมาพร้อมกับคำขอของพวกเขา

บันทึก

ทำไมต้องเป็นฟิลด์ 'อุปกรณ์ประกอบฉาก'? เนื่องจากนั่นเป็นตัวอย่างข้อมูลแบบตัดลงฉันจึงใช้เทคนิคนี้ใน API จำนวนหนึ่งของฉันฉันจึงเก็บข้อมูลการตรวจสอบ / การอนุญาตลงในวัตถุนี้ตัวอย่างด้านล่าง

/*
 * @param {Object} req - Request response object
*/
class ExpressData {

    /*
    * @param {Object} req - express request object
    */
    constructor (req) {

        //Merge all data passed by the client in the request
        this.props = _.merge(req.body, req.params, req.query);

        //Store reference to the user
        this.user = req.user || null;

        //API connected devices (Mobile app..) will send x-client header with requests, web context is implied.
        //This is used to determine how the user is connecting to the API 
        this.client = (req.headers) ? (req.headers["x-client"] || (req.client || "web")) : "web";
    }
} 

1
นี่อาจเป็นความคิดที่ไม่ดีเพราะทำให้การรักษาจุดปลายของคุณยากขึ้น คุณไม่ทราบว่าลูกค้าวิธีการจะใช้ในการส่งผ่านพารามิเตอร์
sdgfsdh

นั่นเป็นหนึ่งในข้อได้เปรียบหลักของวิธีการนี้ที่จะซื่อสัตย์โดยไม่ต้องรู้ว่ามาจากไหน คลาส ExpressData ด้านบนทำหน้าที่เป็นบริดจ์ช่วยให้คุณสามารถโมดุลตรรกะทางธุรกิจของคุณย้ายมันออกจากเส้นทางควบคุมด่วนเช่นคุณไม่ได้อบ 'req.query', 'req.body' ลงในรหัสของคุณสิ่งนี้ยังทำให้ รหัสธุรกิจของคุณสามารถทดสอบได้ง่ายเกินกว่าจะแสดงออกได้อย่างสมบูรณ์
Lee Brindley
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.