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 2012 년

답변:


742
  1. 프로토콜은로 제공됩니다 req.protocol. 여기에 문서

    1. express 3.0 이전에는 프로토콜 이 설정되어 있고 값 이없는 경우 가 http아니라고 가정 할 수 있습니다 .이 경우 프로토콜임을 알고 있습니다req.get('X-Forwarded-Protocol')https
  2. req.get('host')Gopal이 지시 한대로 주최자

  3. URL에 비표준 포트가 필요하지는 않지만 app.listen서버 시작시 전달한 것이기 때문에 포트를 알아야 할 경우 응용 프로그램 상태에있게 됩니다. 그러나 비표준 포트 지역 개발의 경우, 크롬 때문에 호스트 헤더의 포트를 포함하는 것 같다 req.get('host')수익을 localhost:3000예를 들어. 따라서 적어도 표준 포트의 프로덕션 사이트의 경우 (프록시 프록시없이) Express 앱을 직접 탐색하는 경우 host헤더는 URL의 포트와 관련하여 올바른 일을하는 것 같습니다.

  4. 경로는 req.originalUrl(@pgrassant 덕분에) 나온 것입니다. 이 DOES에는 쿼리 문자열이 포함되어 있습니다. req.url 및 req.originalUrl에 대한 문서는 여기입니다 . URL로 수행하려는 작업에 따라에 originalUrl비해 올바른 값일 수도 있고 아닐 수도 있습니다 req.url.

이들을 모두 결합하여 절대 URL을 재구성하십시오.

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

3
@dave 클라이언트는 URL, 포트, 임의의 비 HTTP 가비지뿐만 아니라 원하는 헤더를 보낼 수 있지만, 가짜 또는 부정확 한 헤더는 프로토콜 실패를 유발할 수 있습니다. 예를 들어 가상 호스트 환경에서 잘못된 "호스트"헤더는 완전히 다른 웹 사이트를 표시합니다. X-Forwarded-Protocol의 경우 일반적으로 실제 클라이언트 (브라우저)가 아니라 애플리케이션 앞의 HTTPS를 제공하는 리버스 프록시 (nginx / varnish / apache / whatever)가 보냅니다.
피터 리용

59
또는 req.get('Host')대신 req.host호스트와 포트 섹션을 제공하는 대신 사용 하십시오.
diosney

1
아마도 별도의 질문을 게시하는 것이 가장 좋습니다. 이 질문은 표현에 관한 것입니다.
Peter Lyons

18
host요청 헤더 의 매개 변수는 스푸핑 될 수 있습니다. res.host이 방법을 사용하면 "호스트 헤더 공격"이 발생할 수 있습니다. Django 프레임 워크에는 이러한 공격을 방지하는 데 사용되는 '허용 된 호스트'변수가 있습니다. 완료를 위해 root_url추가 할 수 있는 구성 변수를 사용합니다 req.url. : 공격에 대해 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')만 반환합니다 . 이유를 모르지만 이제는 설정에서 포트 번호를 수집하고 대신 필드를 사용합니다 . hostnamehost
maxkoryukov

1
대신에 pathname나는 당신이 의미하는 것 같아요 path. 검색 / 쿼리 문자열 포함
Félix Sanz

3
쿼리 문자열이있는 URL에는 작동하지 않습니다.
Keith

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

내 잘못이야. 나는 당신이 당신이 어떤 포트를 제공하는지 알고 그 이전에 설정했다고 가정했습니다. 예제를 다시 업데이트하겠습니다. 당신은 또한 그것을 얻을 수 있습니다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 ' user : pass@host.com : 8080 / p / a / t / h? query = string # hash ' 에서 얻을 수있는 user : password는 포함되지 않습니다 .
코드 고유

@CodeUniquely 사실이지만,이 컨벤션은 현재 10 년 이상 사용되지 않기 때문에 실제로 API에 사용자 정보 사양을 작성하는 사람은 없습니다.
Mike

11

프록시 뒤에 Express가 있을 때 req.host/req.hostname을 유효하게하려면 두 가지 조건이 있어야합니다 .

  1. app.set('trust proxy', 'loopback'); app.js에서
  2. X-Forwarded-Host웹 서버에서 자신이 헤더를 지정해야합니다. 예. 아파치, 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;
    }
}

아파치 :

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


1
그래도 아파치 나 nginx에서 올바른 설정이 없다면 127.0.0.1req.get('host')
스파크


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
그것은 프로토콜을 제외한 모든 것을 얻습니다 ... 내가 말할 수있는 것이 있습니까?
Chris Abrams

프로토콜 사용 :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

따라서 bar 컨트롤러 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.