วิธีรับพา ธ การร้องขอด้วยอ็อบเจกต์ req ด่วน


158

ฉันกำลังใช้ express + node.js และฉันมีวัตถุ req คำขอในเบราว์เซอร์คือ / account แต่เมื่อฉันเข้าสู่ req.path ฉันได้รับ '/' --- ไม่ใช่ '/ บัญชี'

  //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 คือ / เมื่อควรจะเป็น / บัญชี ??


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

req.route.path ถูกต้องและเอกสารที่นี่ คุณใช้ express รุ่นไหน?
zemirco

ฉันมีปัญหาเดียวกัน req.routeไม่ได้กำหนด ฉันใช้ express 3.4.4 สิ่งที่อาจทำให้เส้นทางไม่ได้กำหนดไว้?
davidpfahler

@vinayr req.route.path ยังคงให้ฉัน / สร้างแทน / quizzes / สร้างซึ่งเป็น URL ทั้งหมด
Sandip Subedi

นี่เป็นพฤติกรรมที่ตั้งใจไว้ และคุณควรยอมรับมัน ผู้ดูแลของคุณไม่ควรสนใจเส้นทางที่เต็มไป แต่เกี่ยวกับเส้นทาง 'ท้องถิ่น' เท่านั้น นั่นเป็นส่วนหนึ่งหลังจากเส้นทางที่ติดตั้งอยู่ สิ่งนี้ทำให้ฟังก์ชั่นการจัดการง่ายขึ้นเพื่อนำมาใช้ใหม่ในบริบทอื่น ๆ
Stijn de Witt

คำตอบ:


234

หลังจากเล่นไปซักพักแล้วคุณควรใช้:

console.log(req.originalUrl)


3
ฉันคิดว่ามันมีบางอย่างเกี่ยวกับการวางตำแหน่งของมิดเดิลแวร์ แต่คุณถูกต้องมันไม่สมเหตุสมผล
Menztrual

1
มันเป็นมิดเดิลแวร์แน่นอน สิ่งนี้เกิดขึ้นกับเราเตอร์เพิ่มเติมใน Express 4 เช่นกัน เมื่อทั้งสองถูกเมาท์ออกจากเส้นทางที่กำหนดภายในของตัวเองมันจะแกล้งทำเป็นว่ามันออกจากราก นั่นเป็นเรื่องที่ดีสำหรับการแยกออกมา แต่หากินเมื่อคุณไม่รู้ว่าจะได้รับสิ่งที่คุ้มค่าดั้งเดิมได้อย่างไร ขอบคุณสำหรับการโพสต์นี้!
juanpaco

3
ทุกคนที่มาที่นี่ 4.0, req.url ได้รับการออกแบบมาให้มิดเดิลแวร์ที่ไม่แน่นอนสำหรับวัตถุประสงค์ในการกำหนดเส้นทางใหม่และ req.path อาจหายไปจากจุดติดตั้งทั้งนี้ขึ้นอยู่กับที่เรียกว่า expressjs.com/th/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/th/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 คือ / เมื่อควรจะเป็น / บัญชี ??

สาเหตุของเรื่องนี้คือ 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.pathเป็นเพียงนามแฝงสำหรับurl.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.