Wie greife ich nach "?" Auf die GET-Parameter zu? im Express?

527

Ich weiß, wie man die Parameter für Abfragen wie diese erhält:

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

In diesem Fall kann ich req.params.idden Parameter abrufen (z . B. 2in /sample/2).

/sample/2?color=redWie kann ich jedoch für URLs wie auf die Variable zugreifen color?

Ich habe es versucht, req.params.coloraber es hat nicht funktioniert.

Hanfei Sun.
quelle

Antworten:

776

Nachdem ich die Express-Referenz überprüft hatte, stellte ich fest, dass req.query.colorich den Wert zurückgeben würde, den ich suche.

req.params bezieht sich auf Elemente mit einem ':' in der URL und req.query bezieht sich auf Elemente, die mit dem '?' verknüpft sind.

Beispiel:

GET /something?color1=red&color2=blue

Dann im Express, der Handler:

app.get('/something', (req, res) => {
    req.query.color1 === 'red'  // true
    req.query.color2 === 'blue' // true
})
Hanfei Sun.
quelle
Könnten Sie mir bitte sagen, wie ich "id" validieren soll?
Anand Raj
1
@AnandRaj: Was meinst du mit: Wie validiere ich "id"? Welche Art von Validierung möchten Sie? Übrigens können Sie den Wert von idin Ihrer Funktion folgendermaßen ermitteln : var sampleId = req.params.id;.
Jochem Schulenklopper
4
Verwendung req.params.whateverin neuesten Versionen.
Adelriosantiago
3
Denken Sie daran, das req.paramsist anders als req.query! expressjs.com/en/api.html#req.params expressjs.com/en/api.html#req.query @adelriosantiago
caesarsol
81

Verwenden Sie req.query, um den Wert im Abfragezeichenfolgenparameter in der Route abzurufen. Siehe Anfrage . Angenommen, Sie möchten in einer Route http: // localhost: 3000 /? Name = satyam den Wert für den Parameter name abrufen. Der Routen-Handler "Get" lautet dann wie folgt: -

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

});
Satyam Kumar
quelle
Vielleicht ein paar Infos über Querystring, um eine vollständige Antwort zu erhalten
Schuere
67

Update: req.param() ist jetzt veraltet, verwenden Sie diese Antwort daher in Zukunft nicht mehr.


Ihre Antwort ist der bevorzugte Weg, aber ich dachte, ich möchte darauf hinweisen, dass Sie auch mit allen auf URL-, Post- und Routenparameter zugreifen können req.param(parameterName, defaultValue).

In Ihrem Fall:

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

Aus dem Express-Guide:

Die Suche wird in der folgenden Reihenfolge durchgeführt:

  • req.params
  • req.body
  • Anfrage

Beachten Sie, dass in der Anleitung Folgendes angegeben ist:

Der direkte Zugriff auf req.body, req.params und req.query sollte aus Gründen der Übersichtlichkeit bevorzugt werden - es sei denn, Sie akzeptieren wirklich Eingaben von jedem Objekt.

In der Praxis habe ich jedoch festgestellt req.param(), dass dies klar genug ist und bestimmte Arten des Refactorings einfacher macht.

Zugwalt
quelle
53

Abfragezeichenfolge und Parameter sind unterschiedlich.

Sie müssen beide in einer einzelnen Routing-URL verwenden

Bitte überprüfen Sie das folgende Beispiel kann für Sie nützlich sein.

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

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

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

});

Der Link zum Übergeben Ihres zweiten Segments ist Ihr ID-Beispiel: http: // localhost: port / sample / 123

Wenn Sie auf ein Problem stoßen, verwenden Sie bitte Übergeben von Variablen als Abfragezeichenfolge mit '?' Operator

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

     var id = req.query.id; 

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

    });

Holen Sie sich einen Link wie in diesem Beispiel: http: // localhost: port / sample? Id = 123

Beides in einem einzigen Beispiel

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

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

});

Beispiel für einen Link abrufen: http: // localhost: port / sample / 123? Id = 123

Raja Rama Mohan Thavalam
quelle
2
Vielen Dank, diese Antwort war sehr hilfreich!
Bruno Tavares
44

@ Zugwaits Antwort ist richtig. req.param()ist veraltet. Sie sollten verwenden req.params, req.queryoder req.body.

Aber nur um es klarer zu machen:

req.paramswird nur mit den Routenwerten gefüllt. Das heißt, wenn Sie eine Route wie haben /users/:id, können Sie identweder auf die in req.params.idoder zugreifen req.params['id'].

req.queryund req.bodywird mit allen Parametern gefüllt, unabhängig davon, ob sie sich in der Route befinden oder nicht. Natürlich sind Parameter in der Abfragezeichenfolge in req.queryund Parameter in einem Post-Body in verfügbar req.body.

Wenn Sie also Ihre Fragen beantworten, wie colores nicht in der Route enthalten ist, sollten Sie in der Lage sein, sie mit req.query.coloroder zu erhalten req.query['color'].

André Pena
quelle
17

Das Express-Handbuch besagt, dass Sie req.query verwenden sollten, um auf den QueryString zuzugreifen.

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

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

});
Jan Biasi
quelle
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
quelle
7
Vielen Dank für dieses Code-Snippet, das möglicherweise nur begrenzte, sofortige Hilfe bietet. Eine richtige Erklärung würde ihren langfristigen Wert erheblich verbessern, indem sie zeigt, warum dies eine gute Lösung für das Problem ist, und es für zukünftige Leser mit anderen, ähnlichen Fragen nützlicher machen. Bitte bearbeiten Sie Ihre Antwort, um eine Erklärung hinzuzufügen, einschließlich der von Ihnen getroffenen Annahmen.
iBug
2

Eine nette Technik, die ich mit einigen meiner Apps in Express verwendet habe, besteht darin, ein Objekt zu erstellen, das die Abfrage-, Parameter- und Textfelder des Express-Anforderungsobjekts zusammenführt.

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

Dann können Sie in Ihrem Controller-Body oder an einer anderen Stelle im Bereich der Express-Anforderungskette Folgendes verwenden:

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

Dies macht es schön und praktisch, einfach in alle "benutzerdefinierten Daten" einzutauchen, die ein Benutzer möglicherweise mit seiner Anfrage gesendet hat.

Hinweis

Warum das Feld "Requisiten"? Da dies ein abgeschnittenes Snippet war, verwende ich diese Technik in einer Reihe meiner APIs. Ich speichere auch Authentifizierungs- / Autorisierungsdaten auf diesem Objekt, Beispiel unten.

/*
 * @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
quelle
1
Dies ist wahrscheinlich eine schlechte Idee, da es schwieriger ist, Ihre Endpunkte zu verwalten. Sie wissen nicht mehr, mit welcher Methode Clients Parameter übergeben.
SDGFSDH
Das ist tatsächlich einer der Hauptvorteile dieses Ansatzes, um ehrlich zu sein, nicht wissen zu müssen, woher die Felder kommen. Die obige ExpressData-Klasse fungiert als Brücke, mit der Sie Ihre Geschäftslogik modularisieren und von den Express-Controller-Routen entfernen können, dh Sie backen nicht 'req.query', 'req.body' in Ihren Code Ihr Geschäftscode ist leicht zu testen, völlig außerhalb von Express.
Lee Brindley