22

AngularJSでHTML5モードを有効にすることで、$locationサービスはURLを書き換えて、それらからハッシュバンを削除します。これは私のアプリケーションに役立つ素晴らしい機能ですが、ハッシュバンモードへのフォールバックに問題があります。私のサービスには認証が必要であり、アプリケーションから外部認証メカニズムを使用する必要があります。ユーザーがハッシュバンを含むアプリのURLにアクセスしようとすると、最初にユーザーを認証ページにリダイレクトし(認証に成功しない限り、サービスにアクセスすることはありません)、次にユーザーをアプリケーションにリダイレクトします。ハッシュタグはクライアント側からのみ表示されるため、サーバーに到達するまでにルートのどの部分もドロップされます。認証されると、URLを再入力することができ、それは機能しますが、それはユーザーエクスペリエンスに混乱を引き起こす最初の1回です。

私の質問は$location.html5Mode(true)、AngularJSで完全にルーティングするhashbangメソッドをスキップして、サポートされていないブラウザーのフルページリロードのフォールバックに移行する方法はありますか?

私が目指しているものの利用可能な実装の最良の比較は、github.comのフォルダーを閲覧するなどです。ブラウザがページの更新を開始せずにURLの書き換えをサポートしている場合、ページは必要な部分を非同期的にロードします。ブラウザがサポートしていない場合、ユーザーがフォルダをクリックすると、ページ全体が更新されます。これは、ハッシュバンモードを使用する代わりにAngularJSで実現できますか?

4

4 に答える 4

1

次のように、ブラウザーの HTML5 History API チェックで $location と $routeProvider 構成をラップしてみてください。

if (isBrowserSupportsHistoryAPI()) {
    $location.html5Mode(true)
    $routeProvider.when(...);
}

また、パスを変更するために $location を使用する場合は、ラッパーを作成する必要があるかもしれません。(ひどい英語でごめんなさい)

于 2013-03-28T12:24:46.813 に答える
1

$location サービスの機能を試して上書きすることができます。一般的な考え方は、誰かがすでに認証されているかどうかに応じて URL を書き換えるか、html5mode がオンかどうかに関係なく、すべての URL に対して単一のアプローチ (ハッシュバングなし) を使用することです。

ユースケースを完全に理解しているかどうかわからないので、必要な正確なコードを書くことができません。$location サービスをオーバーライド/実装して登録する方法のサンプル実装を次に示します。ハッシュバンが常に排除されるようにします。

app.service('$location', [function() {
    var DEFAULT_PORTS = {
        ftp: 21,
        http: 80,
        https: 443
    };

    angular.extend(this, {
        absUrl: function() {
            return location.href;
        },
        hash: function(hash) {
            return location.hash.substr(1);
        },
        host: function() {
            return location.host;
        },
        path: function(path) {
            if (!path) {
                return location.pathname;
            }
            location.pathname = path;
            return this;
        },
        port: function() {
            return location.port ? Number(location.port) : DEFAULT_PORTS[this.protocol()] || null;
        },
        protocol: function() {
            return location.protocol.substr(0, location.protocol.length - 1);
        },
        replace: function() {
            return this;
        },
        search: function(search, paramValue) {
            if (search || paramValue) {
                return this;
            }
            var query = {};
            location.search.substr(1).split("&").forEach(function(pair) {
                pair = pair.split("="); query[pair[0]] = decodeURIComponent(pair[1]);
            });
            return query;
        },
        url: function(url, replace) {
            return this.path();
        }
    });
}]);
于 2014-06-09T22:21:13.063 に答える