2013-02-19 30 views
22

通過在AngularJS中啓用HTML5模式,$location服務將重寫URL以從其中刪除hashbang。這是一個很棒的功能,它可以幫助我處理我的應用程序,但是它的後備散列模式有一個問題。我的服務需要身份驗證,並且我不得不使用我的應用程序中的外部身份驗證機制。如果用戶試圖通過hashbang訪問我的應用程序的URL,它將首先將它們重定向到身份驗證頁面(不會觸及我的服務,除非成功通過身份驗證),然後將它們重定向回我的應用程序。由於哈希標籤只能從客戶端看到,它會在客戶端打到我的服務器時丟棄路由的任何部分。一旦他們通過身份驗證,他們可能會重新輸入網址,並且會起作用,但那是一個初始時間,會導致用戶體驗中斷。AngularJS HTML5模式降級爲整頁重新加載以代替hashbang

我的問題是,有沒有辦法從$location.html5Mode(true)到不支持瀏覽器的整頁重新加載的回退,跳過完全在AngularJS中進行路由的hashbang方法?

我想要的目標的可用實現的最佳比較將是諸如瀏覽github.com上的文件夾。如果瀏覽器支持在不啓動頁面刷新的情況下重寫URL,頁面將異步加載必要的部分。如果瀏覽器不支持它,當用戶點擊一個文件夾時,會發生整頁刷新。用AngularJS代替使用hashbang模式可以實現嗎?

+1

你有沒有想出一個解決這個?我面臨着類似的情況。 – Jonathan 2014-05-19 19:10:26

回答

1

嘗試包$位置和$ routeProvider配置瀏覽器的HTML5歷史API檢查,像這樣:

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

您可以嘗試覆蓋$ location服務的功能。總體思路是根據某人是否已經通過身份驗證來重寫URL,或者僅對所有URL使用單一方法(無hashbang),而不管html5mode是否打開。

我不確定是否完全理解用例,因此我無法編寫您需要的確切代碼。下面是如何覆蓋/實現了一個樣本實現並註冊$位置服務,只需確保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 
}