【问题标题】:Node JS Express routing not handling / corrrectlyNode JS Express 路由未处理/正确
【发布时间】:2017-03-07 13:06:54
【问题描述】:

我在下面的代码中使用 express 路由器。

第一个定义接受 localhost:3000/tests 是正确的。 第一个定义也接受 localhost:3000/tests/ 这似乎不正确。

当这里接受第二个 URL 时,它会导致我生成的 HTML 具有不正确的相对 URL(例如,当第二个 URL 被接受时变为 /tests/hello 而不是所需的 /hello)。为什么会这样?我应该做些什么来防止带有斜杠的 URL 匹配吗?如果它必须接受两者,我如何生成在这两种情况下都是正确的相对 URL?

//tests.js:

const router = express.Router();

// accepts /tests AND /tests/
router.get('/', function(req, res, next) {
 });

// accepts /tests/new AND /tests/new/
router.get('/new', function(req, res, next) {
 });

//app.js

var tests = require('./routes/tests');
app.use('/tests', tests);

我看到的所有 node.js 示例代码都使用“/”和“/foo”之类的路由,所以我不确定我哪里出错了。

附加编辑:

在创建相对 URL 时,它会构建传入 URL。因此,如果路由处理程序同时接受 /tests 和 /tests/ ,则构建的所有相对 URL 将解析为不同的路径,因为最后一个斜杠对具体路径的形成有很大影响。我应该补充一点,在我部署的环境中,这个应用程序是由 apache 使用代理转发的,因此节点页面的完整 URL 具有类似 example.com/myapp/tests 的上下文。我的开发环境中的路径会有所不同(例如 localhost:3000/tests)

我在几个地方使用相对 URL。

  1. 在路由处理程序中,我可能会执行 res.redirect("foo")。所以如果 传入的 URL 是 example.com/myapp/tests/ 这将导致重定向到 URL example.com/myapp/tests/foo,但如果传入的 URL 是 example.com/myapp/tests 这将导致重定向到示例。 com/myapp/foo。我想要的是第二个,而不是第一个。

  2. 在我生成(使用 EJS 渲染)的 HTML 页面中,包含 CSS 和 HTML 表单、链接、按钮。因此,如果传入的 URL 有尾部斜杠,则类似这样的 CSS 包含的内容解析不正确

    link href = "stylesheets/my.css" rel = "stylesheet">

这些东西的路径都是相对于当前页面的。但是,如果浏览器的位置框将该页面显示为 example.com/myapp/tests/ 我得到的 URL 与 example.com/myapp/tests 不同。在前一种情况下,找不到 CSS,因为它在 /tests/stylessheets/my.css 而不是 /stylesheets/my.css 中寻找它。同样,其他相对 URL 的解析方式也不同,因为可以使用两个不同的传入 URL 有效地生成此页面。

【问题讨论】:

  • 我在整个应用程序中使用诸如/tests/hello 之类的绝对路径没有任何问题,为什么需要相对路径?你能说明你在哪里有相对路径的问题吗?

标签: node.js express routing


【解决方案1】:

结尾斜杠后没有任何内容的 URL 与没有结尾斜杠的 URL 相同。例如,/tests/new/tests/new/ 相同

从您的代码中,tests.js 包含如果您的 app 没有使用它,则不会执行任何操作的路由。

从您的代码中,您将它用于/tests,这意味着对于/tests,它将使用tests.js 中定义的路由。这意味着tests.js 文件中定义的每条路由都将附加在/tests 之后,因为:

app.use("/tests", tests);

如果你想要单独的 /new 路由,你可以执行以下操作。

  1. 在其他文件中定义/new路由,并执行app.use("/", newRoute);
  2. 自行定义那里的路线。 (虽然我不建议这样做,因为它会使您的代码混乱)

【讨论】:

  • 我的应用程序没有使用像 /tests/ 这样的路由,但是如果有人手动将该 URL 输入到位置框,请求就会被发送进来,我的处理程序会接收它并处理它并搞砸相对 URL。除了测试之外,我还有其他路线的其他 js 文件。在示例中,我希望在 tests.js 中处理路由 /tests/new 而不是其他地方。
【解决方案2】:

简短回答:您通过tests 使用此行路由所有内容:

.use("/tests", tests);

Use 定义了中间件,这意味着你的所有路由都通过它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多