Подтвердить что ты не робот

Режим AngularJS HTML5 деградирует до полной перезагрузки страницы вместо хешбанга

Включив режим HTML5 в AngularJS, служба $location перепишет URL-адреса, чтобы удалить из них хешбанг. Это отличная функция, которая поможет мне с моим приложением, но есть проблема с его откатом в режим hashbang. Мой сервис требует аутентификации, и я вынужден использовать внешний механизм аутентификации из своего приложения. Если пользователь попытается перейти к URL-адресу моего приложения с помощью hashbang, он сначала перенаправит их на страницу аутентификации (никогда не коснется моей службы, если она не будет успешно завершена), а затем перенаправит их обратно в мое приложение. Поскольку хэш-тег отображается только с клиентской стороны, он будет отбрасывать все части маршрутов после того, как они попадут на мой сервер. Как только они будут аутентифицированы, они могут повторно ввести URL-адрес, и он будет работать, но это будет одно начальное время, которое вызовет нарушение работы пользователя.

Мой вопрос в том, есть ли какой-либо способ перейти от $location.html5Mode(true) к резервному перезагрузке полноэкранных страниц для не поддерживающих браузеров, пропуская метод hashbang маршрутизации целиком в AngularJS?

Лучшее сравнение доступных реализаций того, для чего я стремлюсь, было бы чем-то вроде просмотра страниц на github.com. Если браузер поддерживает переписывание URL-адреса без инициирования обновления страницы, страница будет асинхронно загружать необходимые части. Если браузер не поддерживает его, когда пользователь нажимает на папку, происходит обновление полной страницы. Может ли это быть достигнуто с помощью AngularJS вместо использования режима hashbang?

4b9b3361

Ответ 1

НЕ перезаписывайте основные функции.

Используйте Modernizr, выполните обнаружение функции, а затем действуйте соответствующим образом.

проверить поддержку API истории

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

Ответ 2

Попробуйте обернуть конфигурацию $location и $routeProvider в браузере API проверки истории HTML5, например:

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

Также может потребоваться создать оболочку в $location, если вы используете ее для изменения пути. (Извините за ужасный английский)

Ответ 3

Почему бы не обработать не аутентифицированную переадресацию на стороне клиента для этой ситуации? Мне нужно узнать немного больше о том, как ваше приложение работает, чтобы дать вам более конкретное решение, но по существу что-то вроде:

  • Пользователь отправляется на маршрут, обработанный AngularJS, сервер обслуживает основной шаблон AngularJS и javascript
  • Пользователь не аутентифицирован, AngularJS обнаруживает это и перенаправляет на страницу аутентификации

У вас может быть что-то в блоке запуска модуля, когда запускается приложение AngularJS:

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

Я подключился к службе, которая выяснила бы, что вы каким-то образом прошли аутентификацию, до вас, как можно проверить файл cookie сеанса, можно было бы поразить ваш API, чтобы спросить. Действительно зависит от того, как вы хотите продолжить проверку подлинности при запуске клиентского приложения.

Ответ 4

Вы можете попробовать и переопределить функциональность службы $location. Общая идея состояла бы в том, чтобы переписать URL-адрес в зависимости от того, кто-то уже прошел проверку подлинности или нет, или просто использовать один подход (без hashbangs) для всех URL-адресов, независимо от того, включен ли html5mode.

Я не уверен, что полностью понимаю прецедент, поэтому я не могу написать точный код, который вам нужен. Ниже приведен пример реализации переопределения/реализации и регистрации службы $location, просто убедитесь, что 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();
        }
    });
}]);