Làm thế nào để có được đường dẫn yêu cầu với đối tượng req express


158

Tôi đang sử dụng express + node.js và tôi có một đối tượng req, yêu cầu trong trình duyệt là / tài khoản nhưng khi tôi đăng nhập req.path tôi nhận được '/' --- không phải '/ tài khoản'.

  //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 là / khi nào nên / tài khoản ??


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

req.route.path là chính xác và được ghi lại ở đây . Phiên bản nào của express bạn đang sử dụng?
zemirco

Tôi có cùng một vấn đề. req.routekhông định nghĩa được. Tôi đang sử dụng express 3.4.4. Điều gì có thể gây ra tuyến đường không được xác định?
davidpfahler

@vinayr req.route.path vẫn cung cấp cho tôi / tạo thay vì / câu đố / tạo, đó là toàn bộ URL
Sandip Subedi

Đây là hành vi dự định. Và bạn nên nắm lấy nó. Trình xử lý của bạn không nên quan tâm đến đường dẫn đầy đủ, mà chỉ về phần 'cục bộ' của đường dẫn. Đó là phần sau con đường nó được gắn vào. Điều này làm cho chức năng xử lý dễ dàng hơn để sử dụng lại trong các bối cảnh khác.
Stijn de Witt

Câu trả lời:


234

Sau khi tự mình chơi một chút, bạn nên sử dụng:

console.log(req.originalUrl)


3
Tôi nghĩ rằng nó có một cái gì đó để làm với định vị của phần mềm trung gian, nhưng bạn đã đúng, nó không có ý nghĩa.
Menztrual

1
Đó chắc chắn là phần mềm trung gian. Điều này xảy ra với các bộ định tuyến bổ sung trong Express 4 là tốt. Khi một trong hai được gắn trên một đường dẫn nhất định, bên trong chính nó sẽ giả vờ rằng nó ra khỏi gốc. Điều đó tốt cho sự cô lập, nhưng khó khăn khi bạn không biết làm thế nào để có được giá trị đầy đủ ban đầu. Cảm ơn bạn đã đăng bài này!
juanpaco

3
Bất cứ ai đến đây vào ngày 4.0, req.url đều được thiết kế để có thể thay đổi bởi phần mềm trung gian cho mục đích định tuyến lại và req.path có thể thiếu các điểm gắn tùy thuộc vào nơi nó được gọi. expressjs.com/en/api.html#req.origenUrl
Christian Davis

3
Nếu bạn không muốn bao gồm chuỗi truy vấn:const path = req.originalUrl.replace(/\?.*$/, '');
Adam Reis

1
Cảnh báo: Đây là một câu trả lời sai lệch, dựa trên câu hỏi OP. Điều này cũng sẽ trả về chuỗi truy vấn (ví dụ: a = b & c = 5) nếu nó có mặt. Xem expressjs.com/en/api.html#req.origenUrl
Ciabaros

60

Trong một số trường hợp bạn nên sử dụng:

req.path

Điều này cung cấp cho bạn đường dẫn, thay vì URL được yêu cầu hoàn chỉnh. Ví dụ: nếu bạn chỉ quan tâm đến trang nào người dùng yêu cầu và không phải tất cả các loại tham số thì url:

/myurl.htm?allkinds&ofparameters=true

req.path sẽ cung cấp cho bạn:

/myurl.html

1
Hãy cẩn thận rằng nếu bạn đang kiểm tra URL này để bao gồm cả kiểm tra dấu gạch chéo nếu nó hợp lệ trong ứng dụng của bạn. (tức là kiểm tra /democũng có khả năng kiểm tra /demo/).
Vinay

Nếu bạn không muốn chuỗi truy vấn được bao gồm: const path = req.origenUrl.replace (/\?.*$/, '');
Adam Reis

req.pathlà cách viết tắt của url.parse(req.url).pathnamevà đây sẽ là câu trả lời được chấp nhận
sertsedat

1
@sertsedat Không chính xác. req.pathcung cấp cho bạn đường dẫn tương đối đến nơi ứng dụng của bạn được gắn kết. Nếu nó được gắn ở gốc hơn điều này là chính xác, nhưng đối với một đường dẫn /my/path, trong một ứng dụng được gắn tại /my, req.urlsẽ cung cấp /path.
Stijn de Witt

21

Để bổ sung, đây là một ví dụ được mở rộng từ tài liệu, bao gồm tất cả những gì bạn cần biết về việc truy cập các đường dẫn / URL trong mọi trường hợp với express:

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()
})

Dựa trên: https://expressjs.com/en/api.html#req.origenUrl

Kết luận: Như câu trả lời của c1moore ở trên, hãy sử dụng:

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 là / khi nào nên / tài khoản ??

Lý do cho điều này là Express trừ đi đường dẫn mà hàm xử lý của bạn được gắn vào, '/account'trong trường hợp này.

tại sao họ lại làm việc này?

Bởi vì nó làm cho nó dễ dàng hơn để sử dụng lại chức năng xử lý. Bạn có thể tạo một hàm xử lý thực hiện những việc khác nhau req.path === '/'req.path === '/goodbye'ví dụ:

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

Sau đó, bạn có thể gắn kết nó với nhiều điểm cuối:

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

Tặng:

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

9

Nếu bạn muốn thực sự chỉ nhận được "đường dẫn" mà không có chuỗi truy vấn, bạn có thể sử dụng urlthư viện để phân tích cú pháp và chỉ nhận một phần đường dẫn của 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();
    }
});

đây chính xác là những gì tôi muốn Sử dụng nó req.query.refnếu đăng nhập thành công
Ryan Wu

Điều này hoạt động độc đáo với mã phổ quát vì nó phù hợp với thông số kỹ thuật Vị trí . Ít điều cần nhớ và dễ dàng hơn để kiểm tra đơn vị trên máy khách và máy chủ.
cchamberlain

req.pathchỉ là một bí danh chourl.parse(req.url).pathname
mhodges

8

Đối với phiên bản 4.x bây giờ bạn có thể sử dụng req.baseUrlbổ sung req.pathđể có được đường dẫn đầy đủ. Ví dụ: OP bây giờ sẽ làm một cái gì đó như:

//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 đang làm việc cho tôi

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

Sau khi thực hiện, tôi thấy các mục sau trong bảng điều khiển và tôi nhận được kết quả hoàn hảo trong trình duyệt của mình.

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.