2013-02-19 4 views
22

AngularJSでHTML5モードを有効にすると、$locationサービスはURLを書き換えてハッシュバングを削除します。これは私のアプリケーションで私を助ける素晴らしい機能ですが、ハッシュバンモードへのフォールバックに問題があります。私のサービスは認証を必要とし、アプリケーションから外部認証メカニズムを使用することを余儀なくされています。ユーザーが自分のアプリケーションのURLにハッシュバングを入れようとすると、まず認証ページにリダイレクトされ(正常に認証されない限り私のサービスには触れません)、アプリケーションにリダイレクトされます。ハッシュタグはクライアント側からしか見えないので、サーバーに到達するまでにルートのどの部分が後ろに来るかは決まりません。認証されると、URLを再入力しても動作しますが、その初期の1時間はユーザーエクスペリエンスに支障をきたします。AngularJS HTML5モードは、ハッシュバンの代わりにフルページのリロードに低下します

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

私が目指しているものの利用可能な実装の最良の比較は、github.comのフォルダをブラウズするなどのものです。ブラウザがページの更新を開始せずにURLの書き換えをサポートしている場合、ページは非同期的に必要な部分をロードします。ブラウザーがそれをサポートしていない場合、ユーザーがフォルダーをクリックすると、フルページリフレッシュが発生します。これは、hashbangモードの代わりにAngularJSで実現できますか?このように、ブラウザのHTML5履歴APIのチェックに$場所と$ routeProvider構成をラップする

+1

は、あなたが今までにこの解決策を考え出すでしたか?私も同様の状況に直面しています。 – Jonathan

答えて

1

試してみてください。

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

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

1

この状況では、クライアント側で認証されていないリダイレクトを処理しないでください。私はあなたのアプリケーションは次のようにあなたのより具体的な解決策が、基本的に何かを与えるために働く正確にどのようにについてもう少し知っておく必要があるだろう:

  1. ユーザーがAngularJSが取り扱うルートに行くと、サーバはAngularJSメインテンプレートを提供しており、 JavaScriptの
  2. ユーザーが認証されていない、AngularJSがこれを検出し、認証ページにリダイレクト

あなたは用のモジュールの実行ブロックで何かを持っていることができるときAngularJSアプリケーションの起動:

module('app',[]) 
    .configure(...yadda...yadda...yadda...) 
    .run(['$location', 'authenticationService', function($location, auth) { 
    if (!auth.isAuthenticated()) { 
     $location.url(authenticationUrl) 
    } 
    }); 

私は、何らかの方法で認証されているかどうかを知るサービスに没頭しました。セッションCookieをチェックしているかどうか、あなたのAPIを尋ねることができます。実際には、クライアントアプリケーションの実行中に認証を確認し続ける方法に依存します。

1

$ロケーションサービスの機能を試して無効にすることができます。一般的な考え方は、誰かがすでに認証されているかどうかに応じてURLを書き換えるか、html5モードがオンかどうかにかかわらず、すべてのURLに対して(hashbangなしで)単一のアプローチを使用することです。

あなたが必要とする正確なコードを書くことができないため、ユースケースを完全に理解しているかどうかはわかりません。ここで/実装をオーバーライドする方法のサンプル実装であり、$ロケーションサービスを登録し、ちょうどhashbangは常に排除であることを確認すること:

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(); 
     } 
    }); 
}]); 
2

コア機能を上書きしないでください。

Modernizrを使用して、機能の検出を行い、それに従って処理を進めます。

履歴APIをサポートするためのチェック

if (Modernizr.history) { 
    // history management works! 
} else { 
    // no history support :(
    // fall back to a scripted solution like History.js 
} 
関連する問題