为什么 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 端点调用。我试图以如下所示的页面历史结束:
- http://www.my.app/my_app#/resources
- http://www.my.app/my_app#/resource/some/link
- http://www.my.app/my_app#/resource/some/other/link
- http://www.my.app/my_app#/resource/some/other/link?page=2
- http://www.my.app/my_app#/resource/some/other/link?page=3
在每种情况下,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:
- http://www.my.app/my_app#/resources
- http://www.my.app/my_app#/resource/some/link
- http://www.my.app/my_app#/resource/some/other/link
很遗憾,您将无法获取“?”后面的项目。不过,使用这个的角色。这些被单独解析为 "this.params"。因此以下 URLs 将 "this.params.page" 设置为适当的值:
- http://www.my.app/my_app#/resource/some/other/link?page=2
- http://www.my.app/my_app#/resource/some/other/link?page=3
不幸的是,你不能在一个 URL 中有多个散列,而 Sammy 只查看从最后一个散列实例开始的 URL 部分,从而解释为什么“#why?not#zoidberg”有效。
受 KnockoutJS SPA tutorial, I'm trying to use Sammy.js 中示例的启发,在单页应用程序中连接一些简单的行为,使用 URL 哈希来跟踪正在访问哪个 API 端点调用。我试图以如下所示的页面历史结束:
- http://www.my.app/my_app#/resources
- http://www.my.app/my_app#/resource/some/link
- http://www.my.app/my_app#/resource/some/other/link
- http://www.my.app/my_app#/resource/some/other/link?page=2
- http://www.my.app/my_app#/resource/some/other/link?page=3
在每种情况下,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:
- http://www.my.app/my_app#/resources
- http://www.my.app/my_app#/resource/some/link
- http://www.my.app/my_app#/resource/some/other/link
很遗憾,您将无法获取“?”后面的项目。不过,使用这个的角色。这些被单独解析为 "this.params"。因此以下 URLs 将 "this.params.page" 设置为适当的值:
- http://www.my.app/my_app#/resource/some/other/link?page=2
- http://www.my.app/my_app#/resource/some/other/link?page=3
不幸的是,你不能在一个 URL 中有多个散列,而 Sammy 只查看从最后一个散列实例开始的 URL 部分,从而解释为什么“#why?not#zoidberg”有效。