Como acessar os parâmetros GET após "?" no Express?

527

Eu sei como obter os parâmetros para consultas como esta:

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

Nesse caso, eu posso usar req.params.idpara obter o parâmetro (por exemplo, 2in /sample/2).

No entanto, para URL /sample/2?color=red, como posso acessar a variável color?

Eu tentei, req.params.colormas não funcionou.

Hanfei Sun
fonte

Respostas:

776

Então, depois de verificar a referência expressa , descobri que req.query.colorme retornaria o valor que estou procurando.

req.params refere-se a itens com um ':' no URL e req.query refere-se a itens associados ao '?'

Exemplo:

GET /something?color1=red&color2=blue

Então, expressamente, o manipulador:

app.get('/something', (req, res) => {
    req.query.color1 === 'red'  // true
    req.query.color2 === 'blue' // true
})
Hanfei Sun
fonte
Você poderia me dizer como validar "id"?
Anand Raj
1
@AnandRaj: o que você quer dizer com: como validar "id"? Que tipo de validação você deseja? BTW, você pode obter o valor de idsua função como esta: var sampleId = req.params.id;.
Jochem Schulenklopper
4
Use req.params.whatevernas versões mais recentes.
adelriosantiago 16/09
3
Mente que req.paramsé 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 obter o valor ele no parâmetro da string de consulta na rota. Consulte req.query . Diga que em uma rota, http: // localhost: 3000 /? Name = satyam, você deseja obter o valor do parâmetro name, então o manipulador de rotas 'Get' será assim: -

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

});
satyam kumar
fonte
talvez algumas informações sobre querystring para obter uma resposta completa
Schuere
67

Atualização: req.param() agora está obsoleta, portanto, daqui para frente, não use esta resposta.


Sua resposta é a maneira preferida de fazê-lo, no entanto, pensei em apontar que você também pode acessar os parâmetros de URL, postagem e rota req.param(parameterName, defaultValue).

No seu caso:

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

Do guia expresso:

a pesquisa é realizada na seguinte ordem:

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

Observe que o guia declara o seguinte:

O acesso direto a req.body, req.params e req.query deve ser favorecido para maior clareza - a menos que você realmente aceite a entrada de cada objeto.

No entanto, na prática, na verdade, sou req.param()suficientemente claro e facilita alguns tipos de refatoração.

Zugwalt
fonte
53

Cadeia de consulta e parâmetros são diferentes.

Você precisa usar ambos no URL de roteamento único

Por favor, verifique o exemplo abaixo pode ser útil para você.

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

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

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

});

Obter o link para passar o seu segundo segmento é o seu exemplo de identificação: http: // localhost: port / sample / 123

Se você estiver enfrentando um problema, use Passando variáveis ​​como string de consulta usando '?' operador

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

     var id = req.query.id; 

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

    });

Obtenha o link como este exemplo: http: // localhost: port / sample? Id = 123

Ambos em um único exemplo

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

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

});

Obter exemplo de link: http: // localhost: port / sample / 123? Id = 123

Raja Rama Mohan Thavalam
fonte
2
Obrigado, esta resposta foi muito útil!
de Bruno Tavares
44

@ A resposta do Zugwait está correta. req.param()está obsoleto. Você deve usar req.params, req.queryoureq.body .

Mas apenas para esclarecer:

req.paramsserá preenchido apenas com os valores da rota. Ou seja, se você tiver uma rota como /users/:id, poderá acessar a opção idem req.params.idou req.params['id'].

req.query e req.body será preenchido com todos os parâmetros, independentemente de estarem ou não na rota. Claro, parâmetros na cadeia de consulta estará disponível em req.querye parâmetros em um corpo pós estará disponível em req.body.

Portanto, respondendo às suas perguntas, como colornão está na rota, você poderá obtê-lo usando req.query.colorou req.query['color'].

André Pena
fonte
17

O manual expresso diz que você deve usar o req.query para acessar o QueryString.

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

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

});
Jan Biasi
fonte
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
fonte
7
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo , mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
iBug 26/01
2

Uma boa técnica que comecei a usar com alguns dos meus aplicativos no express é criar um objeto que mescla os campos de consulta, parâmetros e corpo do objeto de solicitação do 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;

Em seguida, no corpo do seu controlador ou em qualquer outro lugar no escopo da cadeia de solicitações expressas, você pode usar algo como abaixo:

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

Isso torna agradável e prático apenas "investigar" todos os "dados personalizados" que um usuário pode ter enviado com sua solicitação.

Nota

Por que o campo 'adereços'? Como esse foi um fragmento reduzido, eu uso essa técnica em várias APIs, também armazeno dados de autenticação / autorização nesse objeto, exemplo abaixo.

/*
 * @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
fonte
1
Provavelmente, essa é uma péssima idéia, pois dificulta a manutenção dos pontos de extremidade. Você não sabe mais qual método os clientes usarão para passar parâmetros.
Sdgfsdh
Essa é realmente uma das principais vantagens dessa abordagem para ser honesto, sem precisar saber de onde vêm os campos. A classe ExpressData acima atua como uma ponte, permitindo modularizar sua lógica de negócios, afastando-a das rotas expressas do controlador, ou seja, você não está inserindo 'req.query', 'req.body' em seu código, isso também torna seu código comercial é facilmente testável, completamente fora do express.
Lee Brindley