2013-02-19 20 views
22

Bằng cách bật chế độ HTML5 trong AngularJS, dịch vụ $location sẽ ghi đè URL để xóa hashbang khỏi chúng. Đây là một tính năng tuyệt vời mà sẽ giúp tôi với ứng dụng của tôi, nhưng có một vấn đề với dự phòng của nó để chế độ hashbang. Dịch vụ của tôi yêu cầu xác thực và tôi buộc phải sử dụng cơ chế xác thực bên ngoài từ ứng dụng của mình. Nếu người dùng cố gắng truy cập URL cho ứng dụng của tôi bằng hashbang trong đó, trước tiên nó sẽ chuyển hướng họ đến trang xác thực (sẽ không bao giờ chạm vào dịch vụ của tôi trừ khi được xác thực thành công), rồi chuyển hướng họ trở lại ứng dụng của tôi. Là thẻ băm chỉ được nhìn thấy từ phía khách hàng, nó sẽ thả ra bất cứ phần nào của các tuyến đường đến sau khi họ nhấn máy chủ của tôi. Khi chúng được xác thực, chúng có thể nhập lại URL và nó sẽ hoạt động, nhưng đó là lần đầu tiên sẽ gây gián đoạn cho trải nghiệm người dùng.AngularJS Chế độ HTML5 làm suy giảm toàn bộ trang tải lại thay cho hashbang

Câu hỏi của tôi là, có cách nào để đi từ $location.html5Mode(true) đến dự phòng tải lại trang đầy đủ cho các trình duyệt không hỗ trợ, bỏ qua phương pháp định tuyến hashbang hoàn toàn trong AngularJS không?

So sánh tốt nhất các triển khai có sẵn của những gì tôi đang nhắm đến sẽ là một cái gì đó như duyệt qua các thư mục trên github.com. Nếu trình duyệt hỗ trợ viết lại URL mà không bắt đầu làm mới trang, trang sẽ tải không đồng bộ các phần cần thiết. Nếu trình duyệt không hỗ trợ nó, khi người dùng nhấp vào một thư mục, việc làm mới toàn bộ trang sẽ xảy ra. Điều này có thể đạt được với AngularJS thay vì sử dụng chế độ băm không?

+1

Bạn đã bao giờ đưa ra một giải pháp cho điều này? Tôi đang đối mặt với một tình huống tương tự. – Jonathan

Trả lời

1

Cố gắng quấn $ vị trí và $ cấu hình routeProvider trong việc kiểm tra History HTML5 API của trình duyệt, như thế này:

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

cũng có thể bạn cần phải tạo một wrapper đến $ vị trí nếu bạn sử dụng nó để thay đổi con đường. (Xin lỗi vì tiếng anh khủng khiếp)

1

Tại sao không xử lý chuyển hướng chưa được xác thực ở phía máy khách trong trường hợp này? Tôi cần biết thêm một chút về chính xác cách ứng dụng của bạn hoạt động để cung cấp cho bạn giải pháp cụ thể hơn nhưng về cơ bản giống như sau:

  1. Người dùng truy cập tuyến đường được xử lý bởi AngularJS, máy chủ phục vụ mẫu chính AngularJS và javascript
  2. người dùng không được xác thực, AngularJS phát hiện này và chuyển hướng đến trang xác thực

Bạn có thể có một cái gì đó trong khối chạy của mô-đun cho khi AngularJS bắt đầu ứng dụng:

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

Tôi đã đăng ký dịch vụ sẽ tìm hiểu xem bạn có được xác thực bằng cách nào đó hay không, tùy thuộc vào bạn như thế nào, có thể kiểm tra cookie phiên, có thể truy cập API của bạn để hỏi. Thực sự phụ thuộc vào cách bạn muốn tiếp tục kiểm tra xác thực khi ứng dụng khách chạy.

1

Bạn có thể thử và ghi đè chức năng của dịch vụ vị trí $. Ý tưởng chung sẽ là viết lại URL theo một người nào đó đã được xác thực hay không, hoặc chỉ sử dụng một phương pháp duy nhất (không có hashbang) cho tất cả các URL, bất kể html5mode có bật hay không.

Tôi không chắc chắn rằng tôi hoàn toàn hiểu được trường hợp sử dụng nên tôi không thể viết mã chính xác mà bạn cần.Đây là một thực hiện mẫu làm thế nào để ghi đè/dụng cụ và đăng ký các dịch vụ vị trí $, chỉ cần đảm bảo rằng hashbang là luôn loại:

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

KHÔNG ghi đè lên các chức năng cốt lõi.

Sử dụng Modernizr, làm tính năng phát hiện và sau đó tiến hành tương ứng.

séc cho lịch sử hỗ trợ API

if (Modernizr.history) { 
    // history management works! 
} else { 
    // no history support :(
    // fall back to a scripted solution like History.js 
} 
Các vấn đề liên quan