为什么SammyJS不能处理包含与普通哈希相同的斜杠的哈希?

时间:2017-01-04 18:30:21

标签: html url browser single-page-application sammy.js

受到KnockoutJS SPA tutorial中示例的启发,我试图使用Sammy.js在单页面应用程序中连接一些简单的行为,使用URL哈希来跟踪哪个API端点被调用。我试图找到一个如下所示的页面历史记录:

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

问题是,当位置哈希包含正斜杠字符时,我无法让Sammy的路由处理正常工作 - 我不知道为什么。根据{{​​3}},“字符斜杠(”/“)和问号(”?“)允许表示片段标识符中的数据”,所以听起来像我应该只能使用未转义的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始终如一地处理这些碎片?

2 个答案:

答案 0 :(得分:2)

所以,如http://sammyjs.org/docs/routes所述,Sammy.js说“如果你想匹配包含'/'的字符串,它就不起作用。如果你想要,你可以使用Regexp和'splat'”,因此为什么这个例子失败了。

但是,如果你用this.get替换第一个this.get('#(.*)', function () { console.log(this.params['splat']); });,那么它的效果非常好(好吧,“#why?not”错过了not,但这可能在查询字符串中更进一步“#why?not#zoidberg”并不高兴,但我会说你应该坚持使用URL中的一个#)

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

答案 1 :(得分:1)

问题是URL中的Sammy params不能包含斜杠字符。如果是这样,您就不能拥有“#/ path /:var1 / other /:var2”这样的网址。相反,只要您匹配路径,就会想要使用正则表达式,如下例所示(有关详细信息,请参阅enter image description here):

$(function() {
    var fragment = window.location.hash.split("=");
    if (fragment[0] == "#page") {
        $("body").scrollTop($(window).height() * fragment[1]);
    }
});

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

不幸的是,您将无法获得“?”后的项目但是使用这个角色。这些被分别解析为“this.params”。因此,以下URL将“this.params.page”设置为适当的值:

不幸的是,您将无法在URL中使用多个哈希,而Sammy只会查看从最后一个哈希实例开始的URL部分,从而解释为什么“#why?not#zoidberg”的工作原理