Javascript 带有任意字符的AngularJS路由参数
我是AngularJS的新手,所以如果这是显而易见的,请原谅我,但我正在寻找一个能回答这个棘手问题的人。我正在实现一个应用程序,需要将一些参数传递给特定的视图,以显示有关书籍的详细信息。基本上,我希望能够使用以下路由表达式:Javascript 带有任意字符的AngularJS路由参数,javascript,angularjs,url-routing,url-encoding,Javascript,Angularjs,Url Routing,Url Encoding,我是AngularJS的新手,所以如果这是显而易见的,请原谅我,但我正在寻找一个能回答这个棘手问题的人。我正在实现一个应用程序,需要将一些参数传递给特定的视图,以显示有关书籍的详细信息。基本上,我希望能够使用以下路由表达式: bookApp.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/catalog', { templateUrl: 'cat
bookApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/catalog', {
templateUrl: 'cataloglist.htm',
controller: 'catCtrl'
}).
when('/book/:title/:chapter', {
template: 'chapterdetail.htm',
controller: 'chapterCtrl'
}).
otherwise({
template: 'oops ... do not understand that route',
});
}]);
表达式/book/:title/:chapter
应该允许我输入书名。我希望能够通过任何书名在那里。为了确保正确分隔,我将对标题值进行URL编码,这样在编码的值中就不会有斜杠,并且该值将由斜杠字符清楚地分隔。这是构造包含值的URL的正常方法
问题是存在包含斜杠字符的书名(例如,3/5解决方案
),这是编码为的+3%2F5+解决方案
。因此,我们可以构建如下URL:
/app/#/book/The+3%2F5+Solution/The%20Beginning
app.jsp?title=The+3%2F5+Solution&chapter=The%20Beginning
<a href="#/book/{{title | atob}}/{{chapter | atob}}">See Details</a>
然而,我的经验似乎表明,整个值在分解为参数之前是经过URL解码的!这意味着任何带有斜杠的数据值都将被误解为两个值,路由参数的模式匹配将被破坏,并且只传入值的前半部分。此外,该章的名称中也可能有斜杠
如果我正在制作一个REST服务,我会对该值进行URL编码,在对每个片段进行解码之前,URL将被解析为片段。例如,我可以在如下URL中使用查询参数:
/app/#/book/The+3%2F5+Solution/The%20Beginning
app.jsp?title=The+3%2F5+Solution&chapter=The%20Beginning
<a href="#/book/{{title | atob}}/{{chapter | atob}}">See Details</a>
这将正常工作。使用URL编码,我可以传递标题中的任何字符串值。我希望路线参数也能做同样的事情。。。但我已经提到我对AngularJS是新手
在确定片段之前将
%2F
解码为斜杠似乎是一个非常严重的错误。显然,不能将带有斜杠的值作为管线参数传递我在这里遗漏了什么吗?什么样的解决方案可以让我安全地传递一个包含任何可能字符的书名(以及包含任何字符的章节标题)作为路线参数?看看角度,有一种可能实现您想要的:
路径
可以包含以冒号开头、以星形结尾的命名组:
e、 g.:名称*
。当路由匹配时,所有字符都急切地存储在给定的名称下的$routeParams
中。
例如,像/color/:color/largecode/:largecode*\/edit
这样的路由将匹配
/color/brown/largecode/code/with/slashes/edit
并提取:
颜色:棕色
largecode:code/with/slashes
注意示例中:largecode*\
参数末尾的反斜杠。在以星号结尾的命名组的描述中没有,但在示例中有。我没有测试这个,也不知道是否需要反斜杠,所以考虑到它可能是/可能不是必需的
因此,您的问题的解决方案如下所示:
/book/:title*/chapter/:chapter*
注意添加的/chapter/
部分。这是区分两个命名组所必需的。如果您只使用/book/:title*/:chapter*
,则所有内容都属于:title*
命名组。但是,如果使用/:title*/chapter/:chapter*
,angular知道命名组何时结束:何时在路由中遇到/chapter/
。/chapter/
之后的所有内容都属于:chapter*
命名组的范围,因为上述行为,您似乎无法使用URL编码。这意味着您必须使用表示完整Unicode字符集的编码,而不使用斜杠、百分号或加号,也不使用任何其他可能导致URL解码器认为存在要解码的编码值的编码
值的BASE 64编码将实现这一目的,解决方案似乎是定义以下过滤器:
bookApp.filter('btoa', function() {
return function (str) {
return window.btoa(encodeURIComponent(escape(str)));
}
});
bookApp.filter('atob', function() {
return function(str) {
return unescape(decodeURIComponent(window.atob(str)));
}
});
这允许您编写如下代码:
/app/#/book/The+3%2F5+Solution/The%20Beginning
app.jsp?title=The+3%2F5+Solution&chapter=The%20Beginning
<a href="#/book/{{title | atob}}/{{chapter | atob}}">See Details</a>
然后,在接收端,您调用btoa以获取值,以便用于您想要的任何目的。然后将3/5解决方案的值编码为VGHLJTI1MJAZJTJGNUSYNTIWC29SDXRPB24=
,该值将始终是路由参数模式识别器中的单个参数,并准确解码回发送的值
对语言的完全支持。一本名为《代码》的书奥の細道代码>将被编码为JTI1dTU5NjUlMjV1MzA2RSUyNXU3RDMwJTI1dTkwNTM=
——再次避免可能损坏值的任何问题
额外的encodeURIComponent
和escape
调用用于诱使JS将unicode字符串转换为UTF-8编码,然后由window.atob函数进行转换,否则会导致某些高阶unicode字符失败。有关更多信息,请访问(“/catalog/:book”{
templateUrl:'cataloglist.htm',
控制器:“catCtrl”
})
如果您的routeparameter手册是加密的,它可能包含“/”(反斜杠字符),为了在浏览器中将其转换为正确的可执行文件,您必须使用将“/”转换为“%2F”的encodeURIComponent
$window.location='/catalog/'+encodeURIComponent(解决方案/开始的%20) 相关github问题:
解决方法是对参数进行两次编码:
encodeURIComponent(encodeURIComponent("The 3/5 solution"))
如果我理解你的建议,“slug”通常是一种不可逆的转换,例如用于博客文章路径:你扔掉所有难读的字符和空格,得到一条类似于