Comment accéder aux paramètres GET après «?» dans Express?

528

Je sais comment obtenir les paramètres pour des requêtes comme celle-ci:

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

Dans ce cas, je peux utiliser req.params.idpour obtenir le paramètre (par exemple 2dans /sample/2).

Cependant, pour les URL comme /sample/2?color=red, comment puis-je accéder à la variable color?

J'ai essayé req.params.colormais ça n'a pas marché.

Hanfei Sun
la source

Réponses:

777

Donc, après avoir vérifié la référence expresse , j'ai trouvé que req.query.colorcela me rendrait la valeur que je cherchais.

req.params fait référence aux éléments avec un «:» dans l'URL et req.query fait référence aux éléments associés au «?»

Exemple:

GET /something?color1=red&color2=blue

Puis en express, le gestionnaire:

app.get('/something', (req, res) => {
    req.query.color1 === 'red'  // true
    req.query.color2 === 'blue' // true
})
Hanfei Sun
la source
Pourriez-vous me dire comment valider "id"?
Anand Raj
1
@AnandRaj: que voulez-vous dire par: comment valider "id"? Quel type de validation souhaitez-vous? BTW, vous pouvez obtenir la valeur de idvotre fonction comme ceci: var sampleId = req.params.id;.
Jochem Schulenklopper
4
Utiliser req.params.whateverdans les dernières versions.
adelriosantiago
3
req.paramsC'est différent de ça req.query! expressjs.com/en/api.html#req.params expressjs.com/en/api.html#req.query @adelriosantiago
caesarsol
81

Utilisez req.query, pour obtenir la valeur he dans le paramètre de chaîne de requête de l'itinéraire. Reportez-vous à la requête . Dites si dans un itinéraire, http: // localhost: 3000 /? Name = satyam vous voulez obtenir la valeur du paramètre name, alors votre gestionnaire d'itinéraire 'Get' ira comme ceci: -

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

});
satyam kumar
la source
peut-être quelques informations sur querystring pour obtenir une réponse complète
Schuere
67

Mise à jour: req.param() est désormais obsolète, donc à l'avenir, n'utilisez pas cette réponse.


Votre réponse est le moyen préféré de le faire, mais je pensais que je soulignerais que vous pouvez également accéder aux paramètres d'URL, de publication et d'itinéraire avec req.param(parameterName, defaultValue).

Dans ton cas:

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

Du guide express:

la recherche s'effectue dans l'ordre suivant:

  • req.params
  • req.body
  • requête de demande

Notez que le guide indique ce qui suit:

L'accès direct à req.body, req.params et req.query doit être privilégié pour plus de clarté - à moins que vous n'acceptiez vraiment l'entrée de chaque objet.

Cependant, dans la pratique, j'ai trouvé req.param()suffisamment clair et facilite certains types de refactoring.

Zugwalt
la source
53

La chaîne de requête et les paramètres sont différents.

Vous devez utiliser les deux dans une URL de routage unique

Veuillez vérifier l'exemple ci-dessous peut vous être utile.

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

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

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

});

Obtenez le lien pour passer votre deuxième segment est votre exemple id: http: // localhost: port / sample / 123

Si vous rencontrez un problème, veuillez utiliser des variables de passage comme chaîne de requête à l'aide de "?" opérateur

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

     var id = req.query.id; 

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

    });

Obtenez un lien comme cet exemple: http: // localhost: port / sample? Id = 123

Les deux dans un seul exemple

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

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

});

Obtenir un exemple de lien: http: // localhost: port / sample / 123? Id = 123

Raja Rama Mohan Thavalam
la source
2
Merci cette réponse a été très utile!
Bruno Tavares
44

@ La réponse de Zugwait est correcte. req.param()est obsolète. Vous devez utiliser req.params, req.queryou req.body.

Mais pour être plus clair:

req.paramssera rempli uniquement avec les valeurs de l'itinéraire. Autrement dit, si vous avez un itinéraire comme /users/:id, vous pouvez accéder idsoit à req.params.idou à req.params['id'].

req.queryet req.bodyseront remplis avec tous les paramètres, qu'ils soient ou non sur la route. Bien sûr, les paramètres de la chaîne de requête seront disponibles dans req.queryet les paramètres d'un corps de message seront disponibles dans req.body.

Donc, en répondant à vos questions, comme ce colorn'est pas dans l'itinéraire, vous devriez pouvoir l'obtenir en utilisant req.query.colorou req.query['color'].

André Pena
la source
17

Le manuel express indique que vous devez utiliser req.query pour accéder à QueryString.

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

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

});
Jan Biasi
la source
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
la source
7
Merci pour cet extrait de code, qui pourrait fournir une aide immédiate limitée. Une explication appropriée améliorerait considérablement sa valeur à long terme en montrant pourquoi c'est une bonne solution au problème, et la rendrait plus utile aux futurs lecteurs avec d'autres questions similaires. Veuillez modifier votre réponse pour ajouter des explications, y compris les hypothèses que vous avez faites.
iBug
2

Une belle technique que j'ai commencé à utiliser avec certaines de mes applications sur express consiste à créer un objet qui fusionne la requête, les paramètres et les champs de corps de l'objet de demande 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;

Ensuite, dans votre corps de contrôleur, ou n'importe où ailleurs dans le cadre de la chaîne de demande express, vous pouvez utiliser quelque chose comme ci-dessous:

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

Cela rend agréable et pratique de simplement "fouiller" dans toutes les "données personnalisées" qu'un utilisateur peut avoir envoyées avec sa demande.

Remarque

Pourquoi le champ «accessoires»? Étant donné qu'il s'agissait d'un extrait coupé, j'utilise cette technique dans un certain nombre de mes API, je stocke également des données d'authentification / autorisation sur cet objet, exemple ci-dessous.

/*
 * @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
la source
1
C'est probablement une mauvaise idée car cela rend plus difficile la maintenance de vos points de terminaison. Vous ne savez plus quelle méthode les clients utiliseront pour passer les paramètres.
sdgfsdh
C'est en fait l'un des principaux avantages de cette approche pour être honnête, ne pas avoir à savoir d'où viennent les champs. La classe ExpressData ci-dessus agit comme un pont, vous permettant de modulariser votre logique métier, en l'éloignant des routes du contrôleur express, c'est-à-dire que vous ne faites pas "req.query", "req.body" dans votre code, ce qui rend également votre code d'entreprise facilement testable, complètement en dehors de l'express.
Lee Brindley