express req 객체로 요청 경로를 얻는 방법


158

express + node.js를 사용하고 있으며 req 객체가 있는데 브라우저의 요청은 / account이지만 req.path를 기록하면 '/ account'가 아니라 '/'---를 얻습니다.

  //auth required or redirect
  app.use('/account', function(req, res, next) {
    console.log(req.path);
    if ( !req.session.user ) {
      res.redirect('/login?ref='+req.path);
    } else {
      next();
    }
  });

req.path는 / account이어야하는 경우 /


2
TypeError: Cannot read property 'path' of undefined
chovy

req.route.path가 정확하고 여기에 문서화되어 있습니다 . 어떤 Express 버전을 사용하고 있습니까?
zemirco

같은 문제가 있습니다. req.route정의되지 않았습니다. Express를 사용하는 Im 3.4.4. 경로가 정의되지 않은 원인은 무엇입니까?
davidpfahler

@vinayr req.route.path는 / quizzes / create 대신 / create를 제공합니다. 이는 전체 URL입니다.
Sandip

이것은 의도 된 동작입니다. 그리고 당신은 그것을 포용해야합니다. 핸들러는 전체 경로를 신경 쓰지 말고 경로의 '로컬'부분 만 신경 쓰십시오. 그것이 마운트 된 경로 이후의 부분입니다. 따라서 다른 컨텍스트에서 핸들러 기능을 더 쉽게 재사용 할 수 있습니다.
Stijn de Witt

답변:


234

약간의 놀이를 한 후에 다음을 사용해야합니다.

console.log(req.originalUrl)


3
미들웨어의 위치와 관련이 있다고 생각하지만 정확하지만 이해가되지 않습니다.
Menztrual

1
확실히 미들웨어입니다. 이것은 Express 4의 추가 라우터에서도 발생합니다. 주어진 경로에서 마운트되면 루트 자체가 아닌 것처럼 가장합니다. 그것은 격리에는 좋지만 원래의 전체 가치가 무엇인지 얻는 방법을 모른다면 까다 롭습니다. 이것을 게시 해 주셔서 감사합니다!
juanpaco

3
4.0에 도착하면 req.url은 경로 재 지정을 위해 미들웨어로 변경 가능하도록 설계되었으며 req.path는 호출 위치에 따라 장착 지점이 누락 될 수 있습니다. expressjs.com/ko/api.html#req.originalUrl
Christian Davis

3
쿼리 문자열을 포함하지 않으려면const path = req.originalUrl.replace(/\?.*$/, '');
Adam Reis

1
경고 : 이것은 OP 질문에 근거한 잘못된 답변입니다. 쿼리 문자열이 있으면 (예 :? a = b & c = 5) 반환합니다. 참조 expressjs.com/en/api.html#req.originalUrl
Ciabaros

60

어떤 경우에는 다음을 사용해야합니다.

req.path

이렇게하면 요청 된 전체 URL 대신 경로가 제공됩니다. 예를 들어, 사용자가 요청한 페이지에만 관심이 있고 모든 종류의 매개 변수가 아닌 경우 url :

/myurl.htm?allkinds&ofparameters=true

req.path는 다음을 제공합니다.

/myurl.html

1
이 URL에 대해 검사를 수행하는 경우 앱에서 유효한 슬래시에 대한 검사도 포함하도록주의하십시오. (즉, 확인하면 /demo잠재적으로 확인해야합니다 /demo/).
Vinay

쿼리 문자열을 포함하지 않으려면 const path = req.originalUrl.replace (/\?.*$/, '');
Adam Reis

req.path의 속기 url.parse(req.url).pathname와이 허용 대답해야한다
sertsedat

1
@sertsedat 잘못되었습니다. req.path앱이 마운트되는 상대 경로를 제공합니다. 이 루트에 설치되어있는 경우이 정확하지만 경로에 대한보다 /my/path, 응용 프로그램이 장착 내에서 /my, req.url줄 것이다 /path.
Stijn de Witt

21

보충하기 위해 다음은 문서에서 확장 된 예제입니다. 표현식을 사용하면 모든 경우에 경로 / URL 액세스에 대해 알아야 할 모든 내용이 요약되어 있습니다.

app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new?a=b'
  console.dir(req.originalUrl) // '/admin/new?a=b' (WARNING: beware query string)
  console.dir(req.baseUrl) // '/admin'
  console.dir(req.path) // '/new'
  console.dir(req.baseUrl + req.path) // '/admin/new' (full path without query string)
  next()
})

https://expressjs.com/en/api.html#req.originalUrl 기반

결론 :c1moore의 대답은 위의 상태, 사용 :

var fullPath = req.baseUrl + req.path;


9
//auth required or redirect
app.use('/account', function(req, res, next) {
  console.log(req.path);
  if ( !req.session.user ) {
    res.redirect('/login?ref='+req.path);
  } else {
    next();
  }
});

req.path는 / account이어야하는 경우 /

그 이유는 Express가 처리기 기능이 마운트 된 경로를 빼기 때문입니다 ( '/account'이 경우).

그들은 왜 이것을 하는가?

핸들러 함수를보다 쉽게 ​​재사용 할 수 있기 때문입니다. 예를 들어 다음 req.path === '/'과 같은 다른 작업을 수행하는 핸들러 함수를 만들 수 있습니다 req.path === '/goodbye'.

function sendGreeting(req, res, next) {
  res.send(req.path == '/goodbye' ? 'Farewell!' : 'Hello there!')
}

그런 다음 여러 엔드 포인트에 마운트 할 수 있습니다.

app.use('/world', sendGreeting)
app.use('/aliens', sendGreeting)

기부:

/world           ==>  Hello there!
/world/goodbye   ==>  Farewell!
/aliens          ==>  Hello there!
/aliens/goodbye  ==>  Farewell!

9

쿼리 문자열없이 "경로"만 얻으려면 url라이브러리를 사용 하여 URL의 경로 부분 만 구문 분석하고 가져올 수 있습니다 .

var url = require('url');

//auth required or redirect
app.use('/account', function(req, res, next) {
    var path = url.parse(req.url).pathname;
    if ( !req.session.user ) {
      res.redirect('/login?ref='+path);
    } else {
      next();
    }
});

이것은 내가 원하는 것입니다. req.query.ref로그인에 성공한 경우 사용
Ryan Wu

위치 사양을 준수하므로 범용 코드와 잘 작동합니다 . 기억해야 할 것이 적고 클라이언트와 서버에서 단위 테스트가 더 쉽습니다.
cchamberlain

req.pathurl.parse(req.url).pathname
mhodges

8

버전 4.x의 경우 이제 전체 경로를 얻는 데 req.baseUrl추가 기능을 사용할 수 있습니다 req.path. 예를 들어 OP는 이제 다음과 같은 작업을 수행합니다.

//auth required or redirect
app.use('/account', function(req, res, next) {
  console.log(req.baseUrl + req.path);  // => /account

  if(!req.session.user) {
    res.redirect('/login?ref=' + encodeURIComponent(req.baseUrl + req.path));  // => /login?ref=%2Faccount
  } else {
    next();
  }
});

5

req.route.path가 나를 위해 일하고 있습니다.

var pool = require('../db');

module.exports.get_plants = function(req, res) {
    // to run a query we can acquire a client from the pool,
    // run a query on the client, and then return the client to the pool
    pool.connect(function(err, client, done) {
        if (err) {
            return console.error('error fetching client from pool', err);
        }
        client.query('SELECT * FROM plants', function(err, result) {
            //call `done()` to release the client back to the pool
            done();
            if (err) {
                return console.error('error running query', err);
            }
            console.log('A call to route: %s', req.route.path + '\nRequest type: ' + req.method.toLowerCase());
            res.json(result);
        });
    });
};

실행 후 콘솔에서 다음을보고 브라우저에서 완벽한 결과를 얻습니다.

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.