简体   繁体   English

SammyJS为什么不处理包含斜杠的散列与普通散列相同的散列?

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

Inspired by the example in the KnockoutJS SPA tutorial , I'm trying to use Sammy.js to wire up some simple behaviour in a single-page application, using the URL hash to keep track of which API endpoint is being invoked. KnockoutJS SPA教程中的示例的启发,我试图使用Sammy.js在单页应用程序中建立一些简单的行为,使用URL哈希跟踪正在调用的API端点。 I'm trying to end up with a page history that looks like this: 我试图以这样的页面历史记录结束:

In every case, the URL fragment is actually the raw URL that was used to make the API call which rendered the current page. 在每种情况下,URL片段实际上是用于进行呈现当前页面的API调用的原始URL。

The problem is, I can't get Sammy's route handling to work properly when the location hash contains a forward-slash character - and I have no idea why. 问题是,当位置哈希包含正斜杠字符时,我无法使Sammy的路由处理正常工作-我也不知道为什么。 According to RFC3986 , "the characters slash ("/") and question mark ("?") are allowed to represent data within the fragment identifier", so it sounds to me like I should just be able to use unescaped slash and question mark characters in the URL fragment. 根据RFC3986 ,“ 允许字符斜杠(“ /”)和问号(“?”)表示片段标识符中的数据”,这听起来像我应该能够使用未转义的斜杠和问号URL片段中的字符。

Here's a complete repro case covering several different scenarios. 这是一个完整的repro案例,涉及几种不同的情况。 There's two Sammy routes defined - if my understanding of the syntax is correct, one should capture anything containing a hash and the other should match only the empty route. 定义了两个Sammy路由-如果我对语法的理解是正确的,则一个应捕获包含散列的任何内容,另一个应仅匹配空路由。 That's not what's happening, though. 但这不是正在发生的事情。

    <!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>

Any ideas what I need to do to get Sammy to handle these fragments consistently? 有什么想法可以让Sammy始终如一地处理这些碎片?

So, Sammy.js as noted on http://sammyjs.org/docs/routes says "It does not work if you want to match strings that contain '/'. If you want that you can use Regexp and 'splat'", and hence why this example fails. 因此,如http://sammyjs.org/docs/routes上所述的Sammy.js说:“如果要匹配包含'/'的字符串,它将不起作用。如果希望,可以使用Regexp和'splat'” ,并因此说明此示例失败的原因。

If however you replace the first this.get with this.get('#(.*)', function () { console.log(this.params['splat']); }); 但是,如果您将第一个this.get替换为this.get('#(.*)', function () { console.log(this.params['splat']); }); then it works pretty much fine (well, the "#why?not" misses out the not, but that's probably further in the query string and "#why?not#zoidberg" isn't that happy, but I'd say you should stick to a single # in a URL) 然后它就可以正常工作了(嗯,“#why?not”错过了,但是在查询字符串中可能还更远,并且“ #why?not#zoidberg”并不那么高兴,但是我会说你应该在网址中坚持单个#)

https://jsfiddle.net/gymt828r/ demonstrates a fixed instance of this. https://jsfiddle.net/gymt828r/演示了此方法的固定实例。

The problem is that Sammy params within a URL cannot contain a slash character. 问题是URL中的Sammy参数不能包含斜杠字符。 If it did, you could not have URLs like "#/path/:var1/other/:var2". 如果是这样,您将无法使用“#/ path /:var1 / other /:var2”之类的URL。 Instead, you'll want to use a regex whenever you match your path, as in the example below (see http://sammyjs.org/docs/routes for more info): 相反,您将希望在匹配路径时使用正则表达式,如下面的示例所示(有关更多信息,请参见http://sammyjs.org/docs/routes ):

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

The above will output the URL for each of the following paths: 上面将输出以下每个路径的URL:

Unfortunately, you won't be able to get items following a "?" 不幸的是,您将无法获得“?”之后的项目。 character using this, though. 字符使用此。 Those are parsed separately into "this.params". 它们分别解析为“ this.params”。 So the following URLs will have "this.params.page" set to the appropriate value: 因此,以下网址会将“ this.params.page”设置为适当的值:

Unfortunately, you won't be able to have multiple hash in a URL, and Sammy only looks at the portion of the URL starting from the last instance of a hash, thus explaining why "#why?not#zoidberg" works. 不幸的是,您将无法在URL中包含多个哈希,并且Sammy仅查看从哈希的最后一个实例开始的URL部分,从而解释了为什么“ #why?not#zoidberg”起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM