Expressで完全なURLを取得するにはどうすればよいですか?


486

私のサンプルURLが

http://example.com/one/two

私は次のルートを持っていると言います

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

の値はにurlなります/one/two

Expressで完全なURLを取得するにはどうすればよいですか?たとえば、上記の場合、を受け取りhttp://example.com/one/twoます。


6
ちなみに、リクエストオブジェクトを調べて確認することはできますが、私は偽善者であり、ここで見つけました。
Jason Sebring 2017年

回答:


742
  1. プロトコルはとして入手できますreq.protocolここにドキュメント

    1. Express 3.0より前のバージョンでは、プロトコルが設定されていて値が設定されている場合をhttp除いて、プロトコルであると想定できます。req.get('X-Forwarded-Protocol')https
  2. req.get('host')Gopalが示したように、ホストは

  3. うまくいけば、URLに非標準のポートは必要ありませんが、それを知る必要がある場合はapp.listen、サーバーの起動時に渡されたものであるため、アプリケーションの状態にあるはずです。ただし、標準以外のポートでのローカル開発の場合、Chromeはホストヘッダーにポートを含めるため、たとえばをreq.get('host')返しますlocalhost:3000。したがって、少なくとも標準ポートの本番サイトで直接リバースプロキシを使用せずにExpressアプリを参照する場合、hostヘッダーはURLのポートに関して正しいことを行うようです。

  4. パスはreq.originalUrl(thanks @pgrassant)から来ています。これにはクエリ文字列が含まれることに注意してください。req.urlとreq.originalUrlに関するドキュメント。URLをどのように処理するかによってoriginalUrl、と比較して正しい値になる場合とそうでない場合がありますreq.url

これらをすべて組み合わせて、絶対URLを再構築します。

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

3
@daveクライアントは必要なヘッダー(およびURL、ポート、ランダムな非HTTPガベージ)を送信できますが、ある時点で偽のヘッダーや不正確なヘッダーが原因でプロトコルが失敗するだけです。たとえば、仮想ホスト環境では、誤った「ホスト」ヘッダーは完全に異なるWebサイトを表示します。X-Forwarded-Protocolの場合、通常は実際のクライアント(ブラウザー)ではなく、アプリケーションの前でHTTPSを提供するリバースプロキシ(nginx / varnish / apache / whatever)によって送信されます。
Peter Lyons

59
または、req.get('Host')代わりに使用してreq.host、ホストとポートセクションを提供します。
diosney 14年

1
おそらくそのために別の質問を投稿するのが最善です。この質問はエクスプレスについてです。
Peter Lyons 2014

18
hostリクエストヘッダーのパラメータは偽装できます。res.hostこの方法を使用すると、「ホストヘッダー攻撃」の可能性があります。Djangoフレームワークでは、そのような攻撃を防ぐために使用される「許可されたホスト」変数があります。私は、完了root_urlreq.urlためにに追加できるmy である構成変数を使用しています。:攻撃についてskeletonscribe.net/2013/05/...
アミールELDOR

1
req.originalUrlパラメータなしで追加したい場合は、単に実行してくださいreq.originalUrl.split("?").shift()。出典:stackoverflow.com/a/32118818/2037431
Marcos Pereira、

131

自分で連結する代わりに、URLにnode.js APIを使用してURL.format() expressから情報を渡すことができます

例:

var url = require('url');

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

4
私の場合、req.get('host')はポートではなくホスト名の部分のみを返します。理由はわかりませんが、設定からポート番号を収集しhostname、ではなくフィールドを使用していますhost
maxkoryukov

1
代わりにpathname、私はあなたが意味すると思いますpath。どの検索/クエリ文字列が含まれる
フェリックス・サンス

3
これは、クエリ文字列を含むURLでは機能しません。
キース、

37

要求されたURLを取得するのに少しPITAが見つかりました。簡単に表現する方法がないとは思えません。req.requested_urlである必要があります

しかし、ここに私がそれを設定する方法があります:

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

ポート変数を定義する必要がありますか?
Amol M Kulkarni 2013

4
ないreq.port存在?それはExpressのドキュメントにありませんか?
Mitar 2013

私の悪い。私はあなたがあなたがどのポートからサービスを提供しているのか知っていて、その前にそれを設定したと思いました。例をもう一度更新します。あなたはまた、でそれを得ることができますreq.app.settings.port
chovy

req.protocolが空の場合、それはhttpを意味しますか?
Codebeat

これにはクエリが含まれていません。それは完全ではありません。受け入れられた答えはより良いです。
コスタノス

17

url.formatを使用する

var url = require('url');

これはすべてのプロトコルをサポートし、ポート番号を含みます。originalUrlにクエリ文字列がない場合は、次のクリーナーソリューションを使用できます。

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

クエリ文字列がある場合:

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

16

これは、URLを取得するためにreqオブジェクトで呼び出すことができる関数を追加するための優れた方法です

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

これで、必要に応じてオンデマンドで呼び出すことができる関数ができました。


2
これは、ユーザーが含まれていません:パスワードを完全なURLで得ることができることを「ユーザー:pass@host.com:?8080 / P / A / T / Hクエリ=文字列#ハッシュ
コード一意

@CodeUniquelyは真実ですが、この規約は10年以上廃止されて以来、実際にuserinfo仕様をAPIに組み込んでいる人はいないでしょう
Mike

11

req.host/req.hostnameを有効にするには、プロキシがプロキシの背後にある場合、2つの条件が必要です。

  1. app.set('trust proxy', 'loopback'); app.js
  2. X-Forwarded-Hostヘッダーは、Webサーバーで所有者が指定する必要があります。例えば。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
うん、誰もあなたがApacheやnginxのに何の正しい構成を持っていない場合は、あなたが得るだろう、と言わない127.0.0.1からreq.get('host')
Spark.Bao


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

または

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

6

を使用して構築する必要がありreq.headers.host + req.urlます。もちろん、もしあなたが別のポートでホスティングしているような場合、あなたはアイデアを得るでしょう;-)


1
これでプロトコル以外のすべてが取得できます...それを教えてくれるものはありますか?
クリスエイブラムス

プロトコルの使用を取得するには:req.protocol
mrded

6

URLの代わりにoriginalUrlを使用することをお勧めします。

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

ここでoriginalUrlの説明を参照してください:http : //expressjs.com/api.html#req.originalUrl

私たちのシステムでは、次のようなことをしているので、originalUrlは重要です。

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

blah_controllerは次のようになります。

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

したがって、URLの形式は次のとおりです。

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

したがって、バーコントローラのgetハンドラにreq.originalUrlが必要です。


6

私のコードは次のようになります、

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


5

ノードパッケージ「url」を使用します(npm install url)

それはあなたが電話したときです

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

URLのすべてまたは一部を取得する可能性があります。詳細はこちら:https : //github.com/defunctzombie/node-url

次のように使用して、http://www.example.com/の/の後に続くものを変数として使用し、特定のプロファイル(facebookのようなもの:http://www.facebook。 com / username

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

これが機能するには、server.jsファイルで次のようにルートを作成する必要があります。

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

次のようにルートファイルを設定します。

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

2

このようなルートでこの機能を使うことができます

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.protocolhttpまたはhttps を提供し、req.headers.hostwww.google.comのような完全なホスト名 req.originalUrlを提供し、残りpathName(あなたの場合/one/two)を提供します


このソリューションの仕組みについて詳しく教えてください。スタックオーバーフローで解答のみのコードを投稿しないでください。
Arcath、

@Arcathが詳しく説明しました。
Awais Ayub

1

この情報をありがとうございました。これは非常に迷惑です。

これをコードに追加すれば、二度と考える必要はありません。

var app = express();

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

そこで、コンソールへのログなど、他のことも実行または設定できます。


0

以下のコードだけで十分です!

const baseUrl = `${request.protocol}://${request.headers.host}`;
// http://127.0.0.1:3333
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.