¿Cómo acceder a los parámetros GET después de "?" en expreso?

528

Sé cómo obtener los parámetros para consultas como esta:

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

En este caso, puedo usar req.params.idpara obtener el parámetro (por ejemplo, 2en /sample/2).

Sin embargo, para url like /sample/2?color=red, ¿cómo puedo acceder a la variable color?

Lo intenté req.params.colorpero no funcionó.

Hanfei Sun
fuente

Respuestas:

777

Entonces, después de revisar la referencia expresa , descubrí que req.query.colorme devolvería el valor que estaba buscando.

req.params se refiere a elementos con un ':' en la URL y req.query se refiere a elementos asociados con el '?'

Ejemplo:

GET /something?color1=red&color2=blue

Luego, en express, el manejador:

app.get('/something', (req, res) => {
    req.query.color1 === 'red'  // true
    req.query.color2 === 'blue' // true
})
Hanfei Sun
fuente
¿Podría decirme cómo validar "id"?
Anand Raj
1
@AnandRaj: ¿qué quieres decir con: cómo validar "id"? ¿Qué tipo de validación quieres? Por cierto, se puede obtener el valor de iden su función como esta: var sampleId = req.params.id;.
Jochem Schulenklopper
44
Usar req.params.whateveren las últimas versiones.
adelriosantiago
3
Mente que req.paramses diferente de req.query! expressjs.com/en/api.html#req.params expressjs.com/en/api.html#req.query @adelriosantiago
caesarsol
81

Use req.query, para obtener el valor en el parámetro de cadena de consulta en la ruta. Consulte req.query . Digamos que si en una ruta, http: // localhost: 3000 /? Name = satyam desea obtener el valor para el parámetro de nombre, entonces su controlador de ruta 'Obtener' será así: -

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

});
satyam kumar
fuente
quizás algo de información sobre la cadena de consulta para obtener una respuesta completa
Schuere
67

Actualización: req.param() ahora está en desuso, por lo que en adelante no use esta respuesta.


Su respuesta es la forma preferida de hacerlo, sin embargo, pensé en señalar que también puede acceder a los parámetros de URL, publicación y ruta req.param(parameterName, defaultValue).

En tu caso:

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

De la guía express:

la búsqueda se realiza en el siguiente orden:

  • Parametros requeridos
  • req.body
  • req.query

Tenga en cuenta que la guía establece lo siguiente:

Se debe favorecer el acceso directo a req.body, req.params y req.query para mayor claridad, a menos que realmente acepte la entrada de cada objeto.

Sin embargo, en la práctica, he descubierto req.param()que es lo suficientemente claro y facilita ciertos tipos de refactorización.

Zugwalt
fuente
53

La cadena de consulta y los parámetros son diferentes.

Debe usar ambos en una única URL de enrutamiento

Por favor, consulte el siguiente ejemplo puede ser útil para usted.

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

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

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

});

Obtener el enlace para pasar su segundo segmento es su ejemplo de identificación: http: // localhost: port / sample / 123

Si tiene problemas, utilice las variables de paso como cadena de consulta con '?' operador

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

     var id = req.query.id; 

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

    });

Obtenga un enlace como este: http: // localhost: port / sample? Id = 123

Ambos en un solo ejemplo

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

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

});

Obtenga un ejemplo de enlace: http: // localhost: port / sample / 123? Id = 123

Raja Rama Mohan Thavalam
fuente
2
Gracias esta respuesta fue muy útil!
Bruno Tavares
44

La respuesta de @ Zugwait es correcta. req.param()es obsoleto. Deberías usar req.params, req.queryo req.body.

Pero solo para hacerlo más claro:

req.paramsse completará solo con los valores de ruta. Es decir, si tiene una ruta como /users/:id, puede acceder a la ruta iden req.params.ido req.params['id'].

req.queryy req.bodyse completará con todos los parámetros, independientemente de si están o no en la ruta. Por supuesto, los parámetros en la cadena de consulta estarán disponibles en req.queryy los parámetros en un cuerpo de publicación estarán disponibles en req.body.

Entonces, respondiendo a sus preguntas, ya colorque no está en la ruta, debería poder obtenerlas usando req.query.coloro req.query['color'].

André Pena
fuente
17

El manual expreso dice que debe usar req.query para acceder a QueryString.

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

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

});
Jan Biasi
fuente
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!')
)
seme
fuente
77
Gracias por este fragmento de código, que puede proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría en gran medida su valor a largo plazo al mostrar por qué esta es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
iBug el
2

Una buena técnica que comencé a usar con algunas de mis aplicaciones en express es crear un objeto que combine la consulta, los parámetros y los campos del cuerpo del objeto de solicitud de 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;

Luego, en el cuerpo de su controlador, o en cualquier otro lugar dentro del alcance de la cadena de solicitud expresa, puede usar algo como a continuación:

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

Esto hace que sea agradable y práctico "profundizar" en todos los "datos personalizados" que un usuario haya enviado con su solicitud.

Nota

¿Por qué el campo de 'accesorios'? Como era un fragmento reducido, utilizo esta técnica en varias de mis API, también almaceno datos de autenticación / autorización en este objeto, como se muestra a continuación.

/*
 * @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";
    }
} 
Lee Brindley
fuente
1
Esta es probablemente una mala idea porque hace que sea más difícil mantener sus puntos finales. Ya no sabe qué método utilizarán los clientes para pasar los parámetros.
sdgfsdh
Esa es realmente una de las principales ventajas de este enfoque para ser honesto, no tener que saber de dónde provienen los campos. La clase ExpressData anterior actúa como un puente, permitiéndole modularizar su lógica empresarial, alejándola de las rutas del controlador expreso, es decir, no está ingresando 'req.query', 'req.body' en su código, esto también hace que su código de negocio fácilmente comprobable, completamente fuera de express.
Lee Brindley el