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 で別の機能をトリガーします。

バックボーンのバージョンを変更するのは本当に簡単ではありません。

その違いを回避する方法はありますか?

注: 興味深いことに、メタ タグを削除すると Chrome のルーティングが中断されます。

4

3 に答える 3

1

これは、すべてのブラウザーが同じように動作するが、これが起こらないようにするための答えと見なされるべきではありません。私の知る限り、どのバックボーンがトリガーされるかについてはあまり制御できません。によって処理される前に実際に URL をフィルタリングできるわけではありませんRouter

つまり、両方のスタイルのルートを作成できます。これを簡単にするために、utf8 文字列を取得し、ルートの urlencoded バージョンを作成する特別なオブジェクトを作成できます。どちらのルートも同じコールバックを持ちます。

別の可能性として、URL で utf-8 シンボルを使用しないようにして、バグを backbonejs に報告することもできます。両方のルートを urlencoded/urldecoded で作成すると、おそらく JavaScript をサポートするすべてのブラウザーでサイトが機能するようになります。欠点は、n*2ルートを作成する必要があることです。

于 2013-07-09T16:15:21.493 に答える
0

I solved it by adding an additional line in the while loop, inside _bindRoutes, to bind the encoded routes as well:

_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 に答える
0

Have you tried decoding the URL when it's passed to your function? It may be that Chrome decodes the URL for you while Safari does not. 'char%C3%B1' will decode to 'charñ' just fine when using a URI decoder, and it should have no effect on already-decoded strings (assuming the encoding used was the correct one, of course).

decodeURIComponent('char%C3%B1')

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

/*
charñ
*/

Going by http://backbonejs.org/docs/backbone.html#section-156, you may be able to substitute _extractParameters with a version that calls decodeURI or decodeURIComponent on fragment before executing the regular expression.

Another possibility to try, as I just noticed that routes can be regular expressions (see http://backbonejs.org/docs/backbone.html#section-152): if you don't have many of them, you could use something like /char(ñ|%C3%B1)/g, or write a function to produce such a regular expression for the unencoded value, such that makeRegex('charñ') would produce /char(ñ|%C3%B1)/g, or whatever the regular expression would be.

于 2013-07-09T16:04:53.017 に答える