Come ottenere l'URL completo in Express?


486

Supponiamo che il mio URL di esempio sia

http://example.com/one/two

e dico di avere il seguente percorso

app.get('/one/two', function (req, res) {
    var url = req.url;
}

Il valore di urlsarà /one/two.

Come posso ottenere l' URL completo in Express? Ad esempio, nel caso sopra, vorrei ricevere http://example.com/one/two.


6
Cordiali saluti, è possibile controllare l'oggetto richiesta e guardare attraverso ma io sono un ipocrita e l'ho trovato qui.
Jason Sebring,

Risposte:


742
  1. Il protocollo è disponibile come req.protocol. documenti qui

    1. Prima di express 3.0, il protocollo che puoi assumere sia a httpmeno che tu non veda che req.get('X-Forwarded-Protocol')è impostato e ha il valore https, nel qual caso sai che è il tuo protocollo
  2. L'host proviene da req.get('host')come indicato da Gopal

  3. Eventualmente non hai bisogno di una porta non standard nei tuoi URL, ma se avessi bisogno di saperlo lo avresti nello stato della tua applicazione perché è qualunque cosa tu abbia passato app.listenall'avvio del server. Tuttavia, nel caso dello sviluppo locale su una porta non standard, Chrome sembra includere la porta nell'intestazione host, quindi req.get('host')restituisce localhost:3000, ad esempio. Quindi, almeno per i casi di un sito di produzione su una porta standard e per navigare direttamente sulla tua app express (senza proxy inverso), l' hostintestazione sembra fare la cosa giusta per quanto riguarda la porta nell'URL.

  4. Il percorso viene da req.originalUrl(grazie @pgrassant). Nota che questo include la stringa di query. documenti qui su req.url e req.originalUrl . A seconda di cosa si intende fare con l'URL, originalUrlpotrebbe essere o meno il valore corretto rispetto a req.url.

Combina tutti insieme per ricostruire l'URL assoluto.

  var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;

3
@dave un client può inviare qualunque intestazione desideri (così come qualunque URL, porta, spazzatura casuale non HTTP), tuttavia, ad un certo punto intestazioni fasulle o imprecise causeranno semplicemente il fallimento del protocollo. Ad esempio, in un ambiente host virtuale, un'intestazione "host" errata visualizzerà un sito Web completamente diverso. Nel caso di X-Forwarded-Protocol, che di solito non viene inviato dal client effettivo (browser) ma dal proxy inverso (nginx / varnish / apache / qualunque cosa) che serve HTTPS davanti alla tua applicazione.
Peter Lyons,

59
Oppure usa req.get('Host')invece di quello req.hostche dà l'host più la sezione port.
Diosney,

1
Probabilmente è meglio pubblicare una domanda separata per questo. Questa domanda riguarda express.
Peter Lyons,

18
Il hostparametro nelle intestazioni della richiesta può essere falsificato. C'è un possibile "attacco di intestazione host" se si utilizza in res.hostquesto modo. Nel framework Django hanno una variabile "host consentiti" che viene utilizzata per prevenire tale attacco. Uso una variabile di configurazione mia root_urlche può essere aggiunta al req.urlcompletamento. A proposito dell'attacco: skeletonscribe.net/2013/05/…
Amir Eldor,

1
Se si desidera aggiungere req.originalUrlsenza parametri, è sufficiente farlo req.originalUrl.split("?").shift(). Fonte: stackoverflow.com/a/32118818/2037431
Marcos Pereira,

131

Invece di concatenare le cose insieme per conto tuo, potresti invece usare l'API node.js per gli URL e passare URL.format()le informazioni da express.

Esempio:

var url = require('url');

function fullUrl(req) {
  return url.format({
    protocol: req.protocol,
    host: req.get('host'),
    pathname: req.originalUrl
  });
}

4
Nel mio caso req.get('host')restituisce solo la parte del nome host , non la porta. Non so perché, ma ora raccolgo il numero di porta dalle impostazioni e utilizzo il hostnamecampo, anziché host.
maxkoryukov,

1
Invece di pathname, penso che tu intenda path. Che include ricerca / querystring
Félix Sanz,

3
Questo non funziona per gli URL che hanno una stringa di query.
Keith,

37

Ho trovato un po 'un PITA per ottenere l'URL richiesto. Non riesco a credere che non ci sia un modo più semplice per esprimere. Dovrebbe essere solo req.requested_url

Ma ecco come l'ho impostato:

var port = req.app.settings.port || cfg.port;
res.locals.requested_url = req.protocol + '://' + req.host  + ( port == 80 || port == 443 ? '' : ':'+port ) + req.path;

la variabile di porta deve essere definita?
Amol M Kulkarni

4
Esiste req.port? Non è nella documentazione Express?
Mitar,

Colpa mia. Ho pensato che avresti saputo da quale porta stai servendo e che hai impostato prima. Aggiornerò di nuovo l'esempio. Puoi anche ottenerlo conreq.app.settings.port
chovy

quando req.protocol è vuoto, significa http?
Codebeat

Questo non include la query. Non è completo La risposta accettata è migliore.
Kostanos,

17

Utilizzando url.format :

var url = require('url');

Questo supporta tutti i protocolli e include il numero di porta. Se non hai una stringa di query nel tuo URL originale, puoi utilizzare questa soluzione più pulita:

var requrl = url.format({
    protocol: req.protocol,
    host: req.get('host'),
    pathname: req.originalUrl,
});

Se hai una stringa di query:

var urlobj = url.parse(req.originalUrl);
urlobj.protocol = req.protocol;
urlobj.host = req.get('host');
var requrl = url.format(urlobj);

16

Ecco un ottimo modo per aggiungere una funzione che puoi chiamare sull'oggetto req per ottenere l'URL

  app.use(function(req, res, next) {
    req.getUrl = function() {
      return req.protocol + "://" + req.get('host') + req.originalUrl;
    }
    return next();
  });

Ora hai una funzione che puoi chiamare su richiesta se ne hai bisogno.


2
Ciò non include l'utente: password che è possibile ottenere in un URL completo " utente: pass@host.com: 8080 / p / a / t / h? Query = stringa # hash "
Codice univoco il

@CodeSignificativamente vero, ma dal momento che quella convenzione è stata deprecata per oltre un decennio ormai, si spera che nessuno stia effettivamente inserendo le specifiche userinfo nelle loro API
Mike

11

rendere effettivo req.host/req.hostname deve avere due condizioni quando Express dietro i proxy :

  1. app.set('trust proxy', 'loopback'); in app.js
  2. X-Forwarded-Hostl'intestazione deve essere specificata da te nel webserver. per esempio. apache, nginx

nginx :

server {
    listen myhost:80;
    server_name  myhost;
    location / {
        root /path/to/myapp/public;
        proxy_set_header X-Forwarded-Host $host:$server_port;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://myapp:8080;
    }
}

apache :

<VirtualHost myhost:80>
    ServerName myhost
    DocumentRoot /path/to/myapp/public
    ProxyPass / http://myapp:8080/
    ProxyPassReverse / http://myapp:8080/
</VirtualHost>


1
sì, nessuno ha detto che, se non hai una configurazione corretta in apache o nginx, otterrai 127.0.0.1dareq.get('host')
Spark.Bao


7
var full_address = req.protocol + "://" + req.headers.host + req.originalUrl;

o

var full_address = req.protocol + "://" + req.headers.host + req.baseUrl;

6

Devi costruirlo usando req.headers.host + req.url. Naturalmente se stai ospitando in una porta diversa e tale ti viene l'idea ;-)


1
Questo mi dà tutto tranne il protocollo ... c'è qualcosa che può dirmi questo?
Chris Abrams,

Per ottenere il protocollo utilizzare:req.protocol
mrded

6

Suggerirei di utilizzare originalUrl invece di URL:

var url = req.protocol + '://' + req.get('host') + req.originalUrl;

Vedi la descrizione di OriginalUrl qui: http://expressjs.com/api.html#req.originalUrl

Nel nostro sistema, facciamo qualcosa del genere, quindi originalUrl è importante per noi:

  foo = express();
  express().use('/foo', foo);
  foo.use(require('/foo/blah_controller'));

blah_controller si presenta così:

  controller = express();
  module.exports = controller;
  controller.get('/bar/:barparam', function(req, res) { /* handler code */ });

Quindi i nostri URL hanno il formato:

www.example.com/foo/bar/:barparam

Quindi, abbiamo bisogno di req.originalUrl nel controller get gestore di barre.


6

Il mio codice è simile al seguente,

params['host_url'] = req.protocol + '://' + req.headers.host + req.url;


5

Uso il pacchetto del nodo 'url' (npm install url)

Quello che fa è quando chiami

url.parse(req.url, true, true)

ti darà la possibilità di recuperare tutto o parte dell'URL. Maggiori informazioni qui: https://github.com/defunctzombie/node-url

L'ho usato nel modo seguente per ottenere tutto ciò che viene dopo / in http://www.example.com/ da utilizzare come variabile e visualizzare un profilo particolare (un po 'come Facebook: http: //www.facebook. com / nome utente )

    var url = require('url');
    var urlParts = url.parse(req.url, true, true);
    var pathname = urlParts.pathname;
    var username = pathname.slice(1);

Sebbene funzioni, devi creare il tuo percorso in questo modo nel tuo file server.js:

self.routes['/:username'] = require('./routes/users');

E imposta il file del percorso in questo modo:

router.get('/:username', function(req, res) {
 //here comes the url parsing code
}

2

È possibile utilizzare questa funzione nel percorso in questo modo

app.get('/one/two', function (req, res) {
    const url = getFullUrl(req);
}

/**
 * Gets the self full URL from the request
 * 
 * @param {object} req Request
 * @returns {string} URL
 */
const getFullUrl = (req) => `${req.protocol}://${req.headers.host}${req.originalUrl}`;

req.protocolti darà http o https, req.headers.hostti darà il nome host completo come www.google.com, req.originalUrlti darà il resto pathName(nel tuo caso /one/two)


Potresti approfondire come funziona questa soluzione. Evita di pubblicare il codice solo risposte su Stack Overflow.
Arcath,

@Arcath elaborato.
Aspetta Ayub il

1

Grazie a tutti per queste informazioni. Questo è incredibilmente fastidioso.

Aggiungi questo al tuo codice e non dovrai mai più pensarci:

var app = express();

app.all("*", function (req, res, next) {  // runs on ALL requests
    req.fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl
        next()
})

Puoi fare o impostare anche altre cose lì, come accedere alla console.


0

Solo il codice qui sotto era abbastanza per me!

const baseUrl = `${request.protocol}://${request.headers.host}`;
// http://127.0.0.1:3333
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.