Perutean karakter pengganti Express-js untuk mencakup semua yang ada di bawah dan termasuk jalur


96

Saya mencoba untuk memiliki satu rute yang mencakup semuanya /footermasuk /foodirinya sendiri. Saya sudah mencoba menggunakan /foo*yang berfungsi untuk semuanya kecuali tidak cocok /foo. Mengamati:

var express = require("express"),
    app = express.createServer();

app.get("/foo*", function(req, res, next){
  res.write("Foo*\n");
  next();
});

app.get("/foo", function(req, res){
  res.end("Foo\n");
});

app.get("/foo/bar", function(req, res){
  res.end("Foo Bar\n");
});

app.listen(3000);

Keluaran:

$ curl localhost:3000/foo
Foo
$ curl localhost:3000/foo/bar
Foo*
Foo Bar

Apa saja pilihan saya? Yang terbaik yang pernah saya temukan adalah rute /fo*yang tentu saja tidak terlalu optimal karena akan terlalu cocok.


Jika Anda mencegat semua /foo*rute seperti itu, tidakkah Anda ingin menjadikannya middleware?
Raynos

3
Berhati-hatilah dengan apa yang Anda minta: /foo*kecocokan /foo/bartetapi juga kecocokan /foolishyang mungkin tidak Anda inginkan.
Wyck

Jawaban:


112

Saya pikir Anda harus memiliki 2 rute. Jika Anda melihat baris 331 dari koneksi router, * di jalur diganti dengan. + Jadi akan cocok dengan 1 atau lebih karakter.

https://github.com/senchalabs/connect/blob/master/lib/middleware/router.js

Jika Anda memiliki 2 rute yang melakukan tindakan yang sama, Anda dapat melakukan hal berikut agar tetap KERING .

var express = require("express"),
    app = express.createServer();

function fooRoute(req, res, next) {
  res.end("Foo Route\n");
}

app.get("/foo*", fooRoute);
app.get("/foo", fooRoute);

app.listen(3000);

103
app.get(["/foo", "/foo*"], /* function */);mungkin preferensial juga!
Chris Foster

9
Meneruskan serangkaian string juga penting bagi saya. Sayangnya: meneruskan array ke app.VERB () tidak digunakan lagi dan akan dihapus di 4.0
CodeWarrior

10
Meneruskan array string telah dipulihkan di Express 4.9.1.
Pete TNT

30

Router penghubung sekarang telah dihapus ( https://github.com/senchalabs/connect/issues/262 ), penulis menyatakan bahwa Anda harus menggunakan kerangka kerja di atas koneksi (seperti Express) untuk perutean.

Express saat ini diperlakukan app.get("/foo*") sebagai app.get(/\/foo(.*)/), menghilangkan kebutuhan untuk dua rute terpisah. Ini berbeda dengan jawaban sebelumnya (mengacu pada koneksi router yang sekarang dihapus) yang menyatakan bahwa " *dalam jalur diganti dengan .+".

Update: Express saat ini menggunakan "jalan-to-regexp" modul (karena Ekspres 4.0.0) yang mempertahankan perilaku yang sama dalam versi saat ini direferensikan. Tidak jelas bagi saya apakah versi terbaru modul itu mempertahankan perilakunya, tetapi untuk saat ini jawaban ini berlaku.


Jadi, haruskah kita menggunakan. + Atau *?
Tyler Langan

2
Gunakan /\/foo(.+)/jika Anda ingin mencocokkan /foodiikuti dengan satu atau lebih karakter, dan /foo*atau /\/foo(.*)/jika Anda ingin mencocokkan /foodiikuti dengan nol atau lebih karakter.
Johann

12

Tidak perlu memiliki dua rute.

Cukup tambahkan (/*)?di akhir pathstring Anda .

Sebagai contoh, app.get('/hello/world(/*)?' /* ... */)

Berikut adalah contoh yang berfungsi sepenuhnya, silakan salin dan tempel ini ke dalam file .js untuk dijalankan dengan node, dan mainkan di browser (atau curl):

const app = require('express')()

// will be able to match all of the following
const test1 = 'http://localhost:3000/hello/world'
const test2 = 'http://localhost:3000/hello/world/'
const test3 = 'http://localhost:3000/hello/world/with/more/stuff'

// but fail at this one
const failTest = 'http://localhost:3000/foo/world'

app.get('/hello/world(/*)?', (req, res) => res.send(`
    This will match at example endpoints: <br><br>
    <pre><a href="${test1}">${test1}</a></pre>
    <pre><a href="${test2}">${test2}</a></pre>
    <pre><a href="${test3}">${test3}</a></pre>

    <br><br> Will NOT match at: <pre><a href="${failTest}">${failTest}</a></pre>
`))

app.listen(3000, () => console.log('Check this out in a browser at http://localhost:3000/hello/world!'))

9

Dalam array Anda juga dapat menggunakan variabel yang meneruskan ke req.params:

app.get(["/:foo", "/:foo/:bar"], /* function */);

4

Bagi mereka yang sedang mempelajari node / express (seperti saya): jangan gunakan perutean wildcard jika memungkinkan!

Saya juga ingin menerapkan perutean untuk GET / users /: id / apa pun yang menggunakan perutean wildcard. Beginilah cara saya sampai di sini.

Info lebih lanjut: https://blog.praveen.science/wildcard-routing-is-an-anti-pattern/


3
Link saat ini mati. Mungkin itu sama dengan: jonathanong.github.io/wildcard-routing-is-an-anti-pattern.html
Ron Burk

@RonBurk url Anda tampaknya juga mati .. Bagaimana saya bisa memiliki wildcard opsional setelah parameter bernama? "/ sesuatu /: id (/ *)?" tidak bekerja ..
Soichi Hayashi

Mungkin masih akan ada di cache Google untuk sementara waktu: webcache.googleusercontent.com/…
Ron Burk

apakah ada alternatif untuk perutean karakter pengganti jika saya tidak tahu apa yang muncul setelah bagian awal URL?
Michael

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.