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

나는 자신 을 /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*방법은 너무 많이 일치하기 때문에 물론 최적이 아닌 경로 를 지정하는 것입니다.



답변

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


답변

이제 연결 라우터가 제거되었습니다 ( 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 이후)을 사용합니다 . 해당 모듈의 최신 버전이 동작을 유지하는지 여부는 확실하지 않지만 현재로서는이 답변이 유효합니다.


답변

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

문자열 (/*)?끝에 추가하기 만하면 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!'))


답변

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

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


답변

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

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

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

건배, 로버트


답변