AngularJS route parameters with any characters

天大地大妈咪最大 提交于 2019-12-04 04:22:37

Taking a look at the angular's route.js sourcecode, there's described a possibility to achieve what you are looking for:

path can contain named groups starting with a colon and ending with a star: e.g.:name*. All characters are eagerly stored in $routeParams under the given name when the route matches.

For example, routes like /color/:color/largecode/:largecode*\/edit will match /color/brown/largecode/code/with/slashes/edit and extract:
color: brown
largecode: code/with/slashes.

Notice the backslash at the end of the :largecode*\ param in the example. It's not present in the description of named groups ending with a star, but it's there in the example. I didn't test this and don't know whether that backslash is required, so take into account that it it might/might not be required.

Thus, a solution to your question will look like: /book/:title*/chapter/:chapter*

Notice the added /chapter/ part. It is required in order to differentiate between the two named groups. If you'll just use /book/:title*/:chapter*, everything will fall under the :title* named group. However, if you use /:title*/chapter/:chapter*, angular knows when :title* named group ends: when it encounters /chapter/ in the route. Everything after the /chapter/ will fall under the :chapter* named group

The appears to be that you can not use URL Encoding because of the behavior above. This means that you must use an encoding that will represent the full Unicode character set without ever using a slash or a percent sign or a plus sign nor anything else that might cause the URL decoder to think there is an encoded value there to be decoded.

BASE 64 encoding of the value will do the trick, and the solution seems to be to define the following filters:

    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)));
        }
    });

This allows you to write code like this:

<a href="#/book/{{title | atob}}/{{chapter | atob}}">See Details</a>

Then, on the receiving side, you call btoa to get the value back to use for whatever purpose you want. The value The 3/5 solution is then encoded as VGhlJTI1MjAzJTJGNSUyNTIwc29sdXRpb24= which will always be a single parameter in the route parameter pattern recognizer, and is decoded exactly back into the value that was sent.

Full support for languages. A book named 奥の細道 will be encoded as JTI1dTU5NjUlMjV1MzA2RSUyNXU3RDMwJTI1dTkwNTM= -- again avoiding any problem that might corrupt the value.

The extra encodeURIComponent and escape calls are there to trick the JS to convert the unicode string into UTF-8 encoding, which is then transformed by the window.atob function, which would otherwise fail with certain higher order Unicode characters. More information at Mozilla Developer Network

Relevant github issue: https://github.com/angular/angular.js/issues/10479 Workaround is to encode param twice:

encodeURIComponent(encodeURIComponent("The 3/5 solution"))

when('/catalog/:book', { templateUrl: 'cataloglist.htm', controller: 'catCtrl' })

if your routeparameter book is encrypted it may contain '/' (backslash character), inorder to convert it proper executable in browser you must use encodeURIComponent which converts '/' to '%2F'.

$window.location = '/catalog/'+encodeURIComponent(Solution/The%20Beginning);

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!