2

我有这个例子,使用带有 utf-8 非 ascii 字符的路由:

<!DOCTYPE html>
 <html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Backbone Test</title>
 </head>
 <body>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
   <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.3.1/underscore-min.js"></script>
   <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>

   <script>

        (function(){

        window.App = {
            Models: {},
            Collections: {},
            Views: {},
            Router: {}
        };

        })();

        App.Router = Backbone.Router.extend({
            routes: {
                'charñ': 'charChrome',
                'char%C3%B1': 'charSafari'
            },

            charChrome: function(){
                $(document.body).append("Chrome-compatible route triggered.<br/>");
            },

            charSafari: function(){
                $(document.body).append("Safari-compatible route triggered.<br/>");
            },

        });

        new App.Router;
        Backbone.history.start();

   </script>

   <h1>HELLO THERE</h1>
 </body>
 </html>

当页面被调用时:

file://localhost/whatever.html#charñ

...它在 Safari 和 Chrome 上触发不同的功能。

更改主干版本对我来说真的很不容易。

有没有办法避免这种差异?

注意:很有趣,删除 meta 标签会破坏 Chrome 路由。

4

3 回答 3

1

This shouldn't be seen as an answer to that makes every browsers works the same but prevent this from happening. As far as I know, there is no much control on what backone will trigger. It's not like you can really filter the url before it gets handled by the Router.

That said, you can create routes for both style. To make this easier, you can create a special object that will get a utf8 string and create a urlencoded version of the route. Both routes will have the same callback.

On other possibility is to avoid utf-8 symbols in the url and report a bug to backbonejs. Having both routes created with urlencoded/urldecoded will make the site work for possibly every browsers supporting javascript. The downside is that you'll have to create n*2 routes.

于 2013-07-09T16:15:21.493 回答
0

您是否尝试在将 URL 传递给您的函数时对其进行解码?Chrome 可能会为您解码 URL,而 Safari 则不会。'char%C3%B1'使用 URI 解码器时会解码得'charñ'很好,并且它应该对已经解码的字符串没有影响(当然,假设使用的编码是正确的)。

decodeURIComponent('char%C3%B1')

/*
charñ
*/
decodeURIComponent('charñ')

/*
charñ
*/

通过http://backbonejs.org/docs/backbone.html#section-156,您可以在执行正则表达式之前_extractParameters用调用decodeURIdecodeURIComponenton的版本替换。fragment

另一种尝试的可能性,因为我刚刚注意到路由可以是正则表达式(参见http://backbonejs.org/docs/backbone.html#section-152):如果你没有很多,你可以使用一些东西like /char(ñ|%C3%B1)/g,或者编写一个函数来为未编码的值生成这样的正则表达式,这样makeRegex('charñ')会生成/char(ñ|%C3%B1)/g,或者任何正则表达式。

于 2013-07-09T16:04:53.017 回答
0

我通过在 _bindRoutes 内的 while 循环中添加额外的一行来绑定编码的路由来解决它:

_bindRoutes: function() {
  if (!this.routes) return;
  this.routes = _.result(this, 'routes');
  var route, routes = _.keys(this.routes);
  while ((route = routes.pop()) != null) {
    this.route(route, this.routes[route]);
    //add this line:
    this.route(encodeURIComponent(route).replace(/%2F/g,'/').replace(/%3A/g,':'), this.routes[route]);
  }
}
于 2014-03-13T16:34:25.950 回答