为什么 SammyJS 不能像处理普通哈希那样处理包含斜杠的哈希?

Why doesn't SammyJS handle hashes containing slashes the same as normal hashes?

KnockoutJS SPA tutorial, I'm trying to use Sammy.js 中示例的启发,在单页应用程序中连接一些简单的行为,使用 URL 哈希来跟踪正在访问哪个 API 端点调用。我试图以如下所示的页面历史结束:

在每种情况下,URL 片段实际上是原始 URL,用于进行呈现当前页面的 API 调用。

问题是,当位置哈希包含正斜杠字符时,我无法让 Sammy 的路由处理正常工作 - 我不知道为什么。根据 RFC3986,“字符斜线 ("/") 和问号 ("?") 允许代表片段标识符中的数据",所以我觉得我应该能够使用未转义的URL 片段中的斜杠和问号字符。

这是一个完整的重现案例,涵盖了几个不同的场景。定义了两个 Sammy 路由——如果我对语法的理解是正确的,一个应该捕获包含哈希的任何内容,另一个应该只匹配空路由。不过,事实并非如此。

    <!DOCTYPE html>
<html>
<head>
    <title>SammyJS routing demo</title>
    <script type="text/javascript" src="Scripts/jquery-3.1.1.min.js"></script>
    <script type="text/javascript" src="Scripts/sammy-0.7.5.min.js"></script>
</head>
<body>
    <ul>
        <li><a href="#foo">#foo</a> - prints 'foo'</li>
        <li><a href="#/bar">#/bar</a> - prints 'NOPE'</li>
        <li><a href="#!/baz">#!/baz</a> - prints 'NOPE'</li>
        <li><a href="#foo/bar">#foo/bar</a> - prints 'NOPE'</li>
        <li><a href="#foo/bar#bop">#foo/bar#bop</a> - prints 'bop'</li>
        <li><a href="#why?not">#why?not</a> - prints 'why'</li>
        <li><a href="#why?not#zoidberg">#why?not#zoidberg</a> - prints 'why?not#zoidberg'</li>
        <li><a href="#why?not#zoidberg/">#why?not#zoidberg/</a> - prints 'NOPE'</li>
    </ul>
    <script type="text/javascript">
        Sammy(function () {
            this.get('#:url', function () { console.log(this.params.url); });
            this.get('', function () { console.log('NOPE'); });
        }).run();
    </script>
</body>
</html>

有什么想法可以让 Sammy 始终如一地处理这些片段吗?

所以,http://sammyjs.org/docs/routes 中提到的 Sammy.js 说 "It does not work if you want to match strings that contain ‘/’. If you want that you can use Regexp and ‘splat’",因此这个例子失败了。

但是,如果您将第一个 this.get 替换为 this.get('#(.*)', function () { console.log(this.params['splat']); }); 那么它就可以很好地工作(好吧,“#why?not”漏掉了 not,但这可能在查询中更进一步字符串和“#why?not#zoidberg”不是那么开心,但我想说你应该在 URL)

中坚持使用单个 #

https://jsfiddle.net/gymt828r/ 演示了这个的固定实例。

问题是 URL 中的 Sammy 参数不能包含斜杠字符。如果是这样,你就不能有像“#/path/:var1/other/:var2”这样的URLs。相反,您需要在匹配路径时使用正则表达式,如下例所示(有关详细信息,请参阅 http://sammyjs.org/docs/routes):

this.get(/\#(.*)/, function() {
    console.log(this.params['splat']);
});

以上将为以下每个路径输出 URL:

很遗憾,您将无法获取“?”后面的项目。不过,使用这个的角色。这些被单独解析为 "this.params"。因此以下 URLs 将 "this.params.page" 设置为适当的值:

不幸的是,你不能在一个 URL 中有多个散列,而 Sammy 只查看从最后一个散列实例开始的 URL 部分,从而解释为什么“#why?not#zoidberg”有效。