경로를 포함한 모든 것을 포함하는 Express-js 와일드 카드 라우팅


96

나는 자신 을 /foo포함하여 모든 것을 포함하는 하나의 경로를 갖도록 노력하고 있습니다 /foo. 일치하지 않는 /foo*것을 제외하고 모든 작업에 대해 어떤 작업을 사용해 보았습니다 /foo. 관찰 :

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

출력 :

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

내 옵션은 무엇입니까? 내가 생각해 낸 최선의 /fo*방법은 너무 많이 일치하기 때문에 물론 최적이 아닌 경로 를 지정하는 것입니다.


/foo*이와 같은 모든 경로를 가로채는 대신 미들웨어로 만들고 싶지 않습니까?
— Raynos

3
당신이 요구하는 것에주의하십시오 : /foo*성냥 /foo/bar뿐만 아니라 /foolish아마 당신이 의도하지 않았던 성냥 .
— Wyck

답변:


111

2 개의 루트가 필요하다고 생각합니다. 연결 라우터의 331 행을 보면 경로의 *가. +로 바뀌므로 1 개 이상의 문자와 일치합니다.

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

동일한 작업을 수행하는 2 개의 경로가있는 경우 다음을 수행하여 건조 상태를 유지할 수 있습니다.

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

101
app.get(["/foo", "/foo*"], /* function */);또한 우대 할 수 있습니다!
— Chris Foster

9
문자열 배열을 전달하는 것도 나에게 우선적입니다. 불행하게도 : app.VERB ()에 배열을 전달하는 것은 더 이상 사용되지 않으며 4.0에서 제거 될 예정입니다
— CodeWarrior를

10
Express 4.9.1에서는 문자열 배열 전달이 복원되었습니다.
— Pete TNT

30

이제 연결 라우터가 제거되었습니다 ( https://github.com/senchalabs/connect/issues/262 ). 작성자는 라우팅을 위해 연결 위에 프레임 워크 (예 : Express)를 사용해야한다고 언급했습니다.

Express는 현재로 처리 app.get("/foo*") 되므로 app.get(/\/foo(.*)/)두 개의 별도 경로가 필요하지 않습니다. 이것은 " *in a path is replace with .+"라고 언급 한 이전 답변 (지금 제거 된 연결 라우터 참조)과는 대조적 입니다.

업데이트 : 이제 Express는 현재 참조 된 버전에서 동일한 동작 을 유지 하는 "regexp에 대한 경로"모듈 (Express 4.0.0 이후)을 사용합니다 . 해당 모듈의 최신 버전이 동작을 유지하는지 여부는 확실하지 않지만 현재로서는이 답변이 유효합니다.


그렇다면. + 또는 *를 사용해야합니까?
— Tyler Langan 2015-08-22

2
다음에 하나 이상의 문자 를 일치 시키거나 0 개 이상의 문자 를 일치 시키 /\/foo(.+)/려면 사용하십시오 . /foo/foo*/\/foo(.*)//foo
— Johann

12

두 개의 경로가 필요하지 않습니다.

문자열 (/*)?끝에 추가하기 만하면 path됩니다.

예를 들면 app.get('/hello/world(/*)?' /* ... */)

다음은 완전히 작동하는 예제입니다. 이것을 .js 파일에 복사하여 붙여 넣어 노드와 함께 실행하고 브라우저 (또는 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

배열에서 req.params에 전달되는 변수를 사용할 수도 있습니다.

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

3

노드 / 익스프레스 (나처럼)를 배우는 사람들을 위해 : 가능하면 와일드 카드 라우팅을 사용하지 마십시오!

또한 와일드 카드 라우팅을 사용하여 GET / users / : id / whatever에 대한 라우팅을 구현하고 싶었습니다. 이것이 내가 여기에 온 방법입니다.

다행히도 다음 문서도 찾았습니다. http://www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html

건배, 로버트


2
현재 링크가 끊어졌습니다. 아마이었다 동일 : jonathanong.github.io/wildcard-routing-is-an-anti-pattern.html
— 론 버크

@RonBurk 귀하의 URL도 죽은 것 같습니다. 명명 된 매개 변수 뒤에 선택적 와일드 카드를 어떻게 가질 수 있습니까? "/ something / : id (/ *)?" 작동하지 않음 ..
— 쇼이치 하야시

아마 아직 잠시 동안 구글 캐시에있을 것입니다 : webcache.googleusercontent.com/...
— 론 버크

URL의 처음 부분 뒤에 오는 내용을 모르는 경우 와일드 카드 라우팅에 대한 대안이 있습니까?
— Michael

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.