Express/Jade中的相对链接

4
我正在尝试让我的Jade模板编写一个相对于当前URL的超链接(<a>)。
例如,我的视图从http://localhost/cats调用,并且它看起来像这样:
extends layout

block content
  a(href='fluffy') Fluffy

当我点击链接时,它会把我带到http://localhost/fluffy,而不是http://localhost/cats/fluffy
我尝试过以下方法:
  • a(href='./fluffly')
  • a(href='\\fluffy')
  • a(href='/fluffy')
几乎唯一有效的方法就是写出绝对路径,例如a(href='cats/fluffy')。肯定有更好的方法来解决这个问题。

1
我无法重现它,你确定没有打开/cats吗?默认情况下,Express不关心尾随斜杠,并将/cats/cats/视为相同(因此它们都会触发相同的路由)。 - robertklep
你正在使用 <base> 标签吗?如果是,它的值是什么? - gustavohenke
@robertklep 我确定。 @gustavohenke 我没有使用<base>标签..也许我应该使用。事实上,我刚刚检查了HTML输出,它正确地显示为<a href="fluffy">。不幸的是,当我点击它时,它仍然会跳转到http://localhost/fluffy,即使当前页面是http://localhost/cats。 - Travis
@Travis 我希望那只是打错了吧?localhost/cats(不带斜杠结尾)。 - robertklep
@robertklep 哎呀.. 你想把那个作为答案添加吗?我会接受它的 :-) - Travis
2个回答

3
正如您自己已经注意到的那样,当您打开/cats时,预计会有一个指向/fluffy的相对链接:)

背景知识:Express的默认行为是将/cats/cats/视为相同,并且两者都会触发相同的路由。

在创建链接(特别是相对链接)时,您必须考虑到这一点,或者告诉Express将它们视为两个单独的路由:
app.enable('strict routing');

app.get('/cats/', function(req, res) {
  ...
});

这将匹配到/cats/,但不包括/cats。当然,在路由定义中省略尾部斜杠时,这种行为会被反转。


2
如果您正在使用gulp-jade,请添加gulp-data并使用以下代码:
var jade = require('gulp-jade');
var data = require('gulp-data');

gulp.src('**/*.jade')
  .pipe(data(function (file) {
    var relativePath = file.history[0].replace(file.base, ''); //e.g. about/index.jade
    var depth = (relativePath.match(/\//g) || []).length; //e.g. 1
    var relativeRoot = new Array(depth + 1).join( '../' ); //e.g. ../
    return {
      relativeRoot: relativeRoot
    };
  }))
  .pipe(jade())

这将在您的jade模板中提供一个相对根路径relativeRoot,它实质上是:<nothing>../,重复多少次取决于它相对于基本文件夹嵌套的目录数。

然后,在您的模板中:

link(rel='stylesheet', href= relativeRoot + 'assets/main.css')

我不确定file.history是如何生成的,但在我的情况下,[0]指向原始文件名(包括其在磁盘上的绝对路径)


聪明! 对我很有效。 虽然这不是我预期的方法,并且从模板的角度来看,'relativeRoot'变量似乎来自于无处,但我确保详细注释了。 - peteorpeter
对于那些希望所有URL都是相对的人,即使深度为0:var relativeRoot = depth === 0 ? './' : new Array(depth + 1).join('../'); - peteorpeter

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