Як отримати доступ до параметрів GET після "?" в Експресі?


527

Я знаю, як отримати параметри для таких запитів:

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

У цьому випадку я можу використовувати req.params.idдля отримання параметра (наприклад, 2в /sample/2).

Однак для URL-адреси /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"? Яку валідацію ви хочете? До речі, ви можете отримати значення idу вашій функції , як це: var sampleId = req.params.id;.
Йохем Шуленклоппер

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.body
  • запит.запит

Зауважте, у посібнику зазначено наступне:

Прямий доступ до 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

@ Відповідь Цугвайта правильна. req.param()застаріло. Ви повинні використовувати req.params, req.queryабо req.body.

Але лише для того, щоб було зрозуміліше:

req.paramsбуде заповнено лише значеннями маршруту. Тобто, якщо у вас є маршрут , як /users/:idви можете отримати доступ до idабо в req.params.idабо req.params['id'].

req.queryі req.bodyбуде заповнено усіма парамами, незалежно від того, перебувають вони у маршруті чи ні. Звичайно, параметри в рядку запиту будуть доступні в, req.queryа параметри в тілі запиту будуть доступні в req.body.

Отже, відповідаючи на ваші запитання, як colorце не в маршруті, ви повинні мати можливість отримати його за допомогою req.query.colorабо req.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-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' у свій код, це також робить ваш бізнес-код легко перевіряється, повністю поза експресом.
Лі Бріндлі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.