使用Express路由且没有斜杠结尾时无法提供静态文件

13

我想创建一个名为'main'的路由,用于提供静态文件:

app.use('/main',express.static(__dirname+'/public'));

然而,当我执行以下操作时:

http://my.site.dev/main

由于尝试从以下网址获取CSS和JS文件,所以无法下载:

http://my.site.dev/css/styles.css

应该从这里获取文件:

http://my.site.dev/main/css/styles.css

然而,如果我在网址结尾加上斜杠访问我的网站:

http://my.site.dev/main/

所有文件都已经成功地通过了

有没有想法为什么没有尾随斜杠会影响CSS和JS等资源的加载?

2个回答

22

这是一个http问题,不仅仅是Express相关的挑战。该问题在以下讨论:

如果你的URL是/main,而相对URL是css/style.css,它将解析为/css/style.css;但如果你的URL是/main/,相对URL就会解析为/main/css/style.css。

我处理这个问题的策略是通过重定向来添加尾部斜杠。就像在Express中这样:

app.all(/^\/main$/, function(req, res) { res.redirect('/main/'); });
app.use('/main/',express.static(__dirname+'/public'));

或者:

app.enable('strict routing');
app.all('/main', function(req, res) { res.redirect('/main/'); });
app.use('/main/',express.static(__dirname+'/public'));

为了将所有没有尾随斜杠的路由重定向到具有尾随斜杠的相同URL,您可以使用以下代码:app.use(/.*[^\/]$/, function (req, res, next) { res.redirect(req.originalUrl+'/'); });正则表达式 /.*[^\/]$/ 将匹配所有没有尾随斜杠的URL。PS:如果有人能修复我的标记,请帮忙修复一下。我不知道为什么我的代码没有在代码块中。 - JayTheKay
我在@kel的评论中没有得到任何帮助。最终只有一个路由起作用,而另一个与工作路由相同,但对于所有静态内容都有一个尾随斜杠。然而,Trevor的答案似乎有效。 - mez.pahlan

2
在HTML中,JS/CSS文件是如何请求的呢?如果你使用像css/styles.css这样的字符串,那么它会尝试从当前目录获取它们。对于/main的目录是/(就像/main.html一样),而对于/main/的目录则是/main/。一个快速的解决方法是在你的HTML中使用/main/css/styles.css

我正在使用: <link href="css/styles.css" /> 在链接href中使用完整路径没有意义。 - Abadaba
2
个人而言,我总是使用完整路径来获取资源文件,因为我从不使用“file://”协议进行调试。无论如何,你在这里只有几个选择: (1) 使用资源的完整路径; (2) 在Express中使用中间件或其他东西,以确保始终存在一个尾部斜杠; (3) 在呈现时使用本地文件,告诉您的布局要使用哪个路径,例如在Jade中 link(href="#{subdir}/css/styles.css") (4) 在HTML中使用 <base href /> 手动设置基本URI(似乎是最糟糕的解决方案)。 - Michelle Tilley
我没有使用file://协议,我的网站通过http://my.site.dev/main本地托管。 - Abadaba
如果是这样的话,为什么不使用完整路径呢?如果您使用相对路径,则每个子路径都会得到不同的结果(例如,从“/main”、“/main/something”和“/main/something/else”开始的相对路径都是不同的)。 - Michelle Tilley
在Apache中,您可以在conf文件中提供别名,将主URL路径指向文件系统中的目录。您永远不需要在脚本包含中提及别名路径名称,因为根始终指向该目录。我希望在node.js/connect/express中使用非尾随斜杠实现相同的功能。我想这是一些正则表达式的问题,或者我需要将main重定向到main/? - Abadaba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接