Jak uzyskać dostęp do parametrów GET po „?” w ekspresie?

527

Wiem, jak uzyskać parametry dla takich zapytań:

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

W tym przypadku można użyć req.params.id, aby uzyskać parametru (np 2w /sample/2).

Jednak w przypadku adresu URL /sample/2?color=red, jak mogę uzyskać dostęp do zmiennej color?

Próbowałem, req.params.colorale to nie zadziałało.

Hanfei Sun
źródło

Odpowiedzi:

776

Tak więc, po sprawdzeniu wyraźnego odwołania , znalazłem, req.query.colorże zwróci mi wartość, której szukam.

req.params odnosi się do elementów ze znakiem „:” w adresie URL, a req.query odnosi się do elementów powiązanych z „?”

Przykład:

GET /something?color1=red&color2=blue

Następnie w trybie ekspresowym program obsługi:

app.get('/something', (req, res) => {
    req.query.color1 === 'red'  // true
    req.query.color2 === 'blue' // true
})
Hanfei Sun
źródło
Czy możesz mi powiedzieć, jak zweryfikować „identyfikator”?
Anand Raj
1
@AnandRaj: co masz na myśli: jak sprawdzić poprawność „id”? Jakiego rodzaju walidacji chcesz? BTW, można uzyskać wartość idw funkcji takich jak to: var sampleId = req.params.id;.
Jochem Schulenklopper
4
Użyj req.params.whateverw najnowszych wersjach.
adelriosantiago
3
Umysł req.paramsróżni się od req.query! expressjs.com/en/api.html#req.params expressjs.com/en/api.html#req.query @adelriosantiago
caesarsol
81

Użyj req.query, aby uzyskać wartość parametru ciągu zapytania w trasie. Zobacz zapytanie . Powiedz, że jeśli na trasie http: // localhost: 3000 /? Name = satyam chcesz uzyskać wartość parametru name, wówczas procedura obsługi trasy „Get” będzie wyglądać następująco: -

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

});
satyam kumar
źródło
być może jakieś informacje na temat querystring, aby uzyskać pełną odpowiedź
Schuere
67

Aktualizacja: req.param() jest już przestarzała, więc nie używaj tej odpowiedzi.


Twoja odpowiedź jest preferowanym sposobem na zrobienie tego, jednak pomyślałem, że zwrócę uwagę, że możesz również uzyskać dostęp do parametrów adresu URL, wpisu i trasy req.param(parameterName, defaultValue).

W Twoim przypadku:

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

Z przewodnika ekspresowego:

wyszukiwanie odbywa się w następującej kolejności:

  • req.params
  • wymagane ciało
  • wymagane. zapytanie

Uwaga: przewodnik zawiera następujące informacje:

Bezpośredni dostęp do req.body, req.params i req.query powinien być preferowany dla przejrzystości - chyba że naprawdę akceptujesz dane wejściowe z każdego obiektu.

Jednak w praktyce okazało się, req.param()że jest wystarczająco jasny i ułatwia pewne rodzaje refaktoryzacji.

Zugwalt
źródło
53

Ciąg zapytania i parametry są różne.

Musisz użyć obu w jednym adresie URL routingu

Sprawdź poniższy przykład, który może Ci się przydać.

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

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

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

});

Uzyskaj link do przekazania drugiego segmentu to Twój przykładowy identyfikator: http: // localhost: port / sample / 123

Jeśli napotykasz problem, użyj parametru Przekazywanie zmiennych jako ciągu zapytania za pomocą „?” operator

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

     var id = req.query.id; 

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

    });

Uzyskaj link podobny do tego: http: // localhost: port / sample? Id = 123

Oba w jednym przykładzie

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

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

});

Uzyskaj przykładowy link: http: // localhost: port / sample / 123? Id = 123

Raja Rama Mohan Thavalam
źródło
2
Dzięki, ta odpowiedź była bardzo pomocna!
Bruno Tavares
44

@ Odpowiedź Zugwaita jest poprawna. req.param()jest przestarzałe. Należy użyć req.params, req.querylub req.body.

Ale żeby to wyjaśnić:

req.paramszostaną wypełnione tylko wartościami trasy. Oznacza to, że jeśli masz trasę typu /users/:id, możesz uzyskać dostęp do idw req.params.idlub req.params['id'].

req.queryi req.bodyzostaną wypełnione wszystkimi parametrami , niezależnie od tego, czy znajdują się na trasie. Oczywiście parametry w ciągu zapytania będą dostępne w, req.querya parametry w treści postu będą dostępne w req.body.

Odpowiadając na pytania, ponieważ colornie ma go na trasie, powinieneś być w stanie je uzyskać za pomocą req.query.colorlub req.query['color'].

André Pena
źródło
17

Instrukcja ekspresowa mówi, że powinieneś użyć req.query, aby uzyskać dostęp do QueryString.

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

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

});
Jan Biasi
źródło
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
źródło
7
Dziękujemy za ten fragment kodu, który może zapewnić pewną ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie byłoby znacznie poprawić swoją długoterminową wartość pokazując dlaczego jest to dobre rozwiązanie problemu, a byłoby bardziej użyteczne dla czytelników przyszłości z innymi, podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
iBug
2

Fajną techniką, którą zacząłem stosować z niektórymi moimi aplikacjami w express, jest stworzenie obiektu, który łączy zapytanie, parametry i pola treści obiektu żądania 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;

Następnie w ciele kontrolera lub w dowolnym innym miejscu w łańcuchu wyraźnych żądań możesz użyć czegoś takiego jak poniżej:

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

To sprawia, że ​​miło i wygodnie jest po prostu „zagłębić się” we wszystkie „niestandardowe dane”, które użytkownik mógł wysłać z prośbą.

Uwaga

Dlaczego pole „rekwizyty”? Ponieważ był to fragment kodu, używam tej techniki w wielu moich interfejsach API, przechowuję również dane uwierzytelniające / autoryzacyjne w tym obiekcie, przykład poniżej.

/*
 * @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
źródło
1
Jest to prawdopodobnie zły pomysł, ponieważ utrudnia utrzymanie punktów końcowych. Nie wiesz już, jaką metodą klienci będą przekazywać parametry.
sdgfsdh
Jest to w rzeczywistości jedna z głównych zalet tego podejścia, aby być uczciwym, nie wiedząc, skąd pochodzą pola. Powyższa klasa ExpressData działa jak pomost, pozwalając na modularyzację logiki biznesowej, odsuwając ją od tras kontrolera ekspresowego, tj. Nie wprowadzasz do kodu „req.query”, „req.body” w kodzie, to także powoduje, że Twój kod biznesowy można łatwo przetestować, całkowicie poza ekspresowym.
Lee Brindley,