$ lokalizacja / przełączanie między trybem html5 i hashbang / przepisywanie linków

Miałem wrażenie, że Angular przepisuje adresy URL, które pojawiają się w atrybutach href tagów anchor w ramach tempaltes, tak aby działały zarówno w trybie html5, jak i w trybie hashbang. Dokumentacja dla usługi lokalizacji wydaje się mówić, że przepisywanie linków HTML zajmuje się sytuacją hashbang. Spodziewałbym się więc, że gdy nie w trybie HTML5, zostaną wstawione hashe, a w trybie HTML5 Nie.

Wydaje się jednak, że nie trwa przepisywanie. Poniższy przykład nie pozwala mi po prostu zmienić trybu. Wszystkie łącza w aplikacji muszą być przepisane ręcznie (lub pochodzące ze zmiennej w czasie wykonywania. Czy muszę ręcznie przepisać wszystkie adresy URL w zależności od trybu?

Nie widzę żadnego przepisywania url po stronie klienta dzieje się w Angular 1.0.6, 1.1.4 lub 1.1.3. Wydaje się, że wszystkie wartości href muszą być poprzedzone # / dla trybu hashbang i / dla trybu html5.

Czy Jest jakiś konfiguracja konieczna do przepisania? Źle odczytałem dokumenty? Robisz coś głupiego?

Oto mały przykład:

<head>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.3/angular.js"></script>
</head>

<body>
    <div ng-view></div>
    <script>
        angular.module('sample', [])
            .config(
        ['$routeProvider', '$locationProvider',
            function ($routeProvider, $locationProvider) {

                //commenting out this line (switching to hashbang mode) breaks the app
                //-- unless # is added to the templates
                $locationProvider.html5Mode(true);

                $routeProvider.when('/', {
                    template: 'this is home. go to <a href="/about"/>about</a>'
                });
                $routeProvider.when('/about', {
                    template: 'this is about. go to <a href="/"/>home</a'
                });
            }
        ])
            .run();
    </script>
</body>

Dodatek: czytając ponownie moje pytanie, widzę, że użyłem terminu "przepisywanie" bez obfitości jasności co do tego, kto i kiedy chciałem zrobić przepisywanie. Pytanie dotyczy tego, jak zmusić Angular do przepisania adresów URL podczas renderowania ścieżek i jak zmusić go do równomiernej interpretacji ścieżek w kodzie JS dwa tryby. To jest nie o tym, jak sprawić, by serwer WWW wykonywał przepisywanie żądań zgodnych z HTML5.

Author: laurelnaiad, 2013-05-21

4 answers

Dokumentacja nie jest zbyt jasna co do routingu AngularJS. Mówi o trybie Hashbang i HTML5. W rzeczywistości routing AngularJS działa w trzech trybach:

  • Hashbang Mode
  • HTML5 Mode
  • Hashbang w trybie HTML5

Dla każdego trybu istnieje odpowiednia Klasa LocationUrl (LocationHashbangUrl, LocationUrl i LocationHashbangInHTML5Url).

Aby symulować przepisywanie adresów URL, musisz ustawić html5mode na true i udekorować Klasa $sniffer wygląda następująco:

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});

Teraz wyjaśnię to bardziej szczegółowo:

Hashbang Mode

Konfiguracja:

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
});
$locationProvider
  .html5Mode(false)
  .hashPrefix('!');

Jest to przypadek, gdy musisz użyć adresów URL z hashami w plikach HTML, takich jak w

<a href="index.html#!/path">link</a>

W przeglądarce należy użyć następującego linku: http://www.example.com/base/index.html#!/base/path

Jak widać w trybie Pure Hashbang wszystkie linki w plikach HTML muszą zaczynać się od bazy np. " index.html#!".

HTML5 Mode

Konfiguracja:

$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true);

Powinieneś ustawić bazę w pliku HTML

<html>
  <head>
    <base href="/">
  </head>
</html>

W tym trybie można używać linków bez # w plikach HTML

<a href="/path">link</a>

Link w przeglądarce:

http://www.example.com/base/path

Hashbang w trybie HTML5

Ten tryb jest aktywowany, gdy faktycznie używamy trybu HTML5, ale w niezgodnej przeglądarce. Możemy symulować ten tryb w zgodnej przeglądarce dekorując usługę $sniffer i ustawiając historię na fałsz.

Konfiguracja:

$provide.decorator('$sniffer', function($delegate) {
  $delegate.history = false;
  return $delegate;
});
$routeProvider
  .when('/path', {
    templateUrl: 'path.html',
  });
$locationProvider
  .html5Mode(true)
  .hashPrefix('!');

Ustaw bazę w pliku HTML:

<html>
  <head>
    <base href="/">
  </head>
</html>

W tym przypadku linki mogą być również zapisywane bez hasha w pliku HTML

<a href="/path">link</a>

Link w przeglądarce:

http://www.example.com/index.html#!/base/path
 360
Author: jupiter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-25 09:43:50

Future readers, jeśli używasz Angular 1.6 , musisz również zmienić hashPrefix:

appModule.config(['$locationProvider', function($locationProvider) {
    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix('');
}]);

Nie zapomnij ustawić bazy w HTML <head>:

<head>
    <base href="/">
    ...
</head>

Więcej informacji o changelog proszę..

 8
Author: Mistalis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-08 11:46:47

Trochę mi to zajęło, więc tak to działa - Angular WebAPI ASP Routing Bez # dla SEO

  1. Dodaj do indeksu.html - base href="/">
  2. Dodaj $ locationProvider.html5Mode (true); do aplikacji.config

  3. Potrzebowałem pewnego kontrolera (który był w kontrolerze domowym) do zignorowania przy przesyłaniu obrazów, więc dodałem tę regułę do RouteConfig

         routes.MapRoute(
            name: "Default2",
            url: "Home/{*.}",
            defaults: new { controller = "Home", action = "SaveImage" }
        );
    
  4. In Global.asax dodać następujące - upewniając się, aby zignorować api i ścieżki przesyłania obrazów pozwalają im działać normalnie, w przeciwnym razie przekierowują Wszystko inne.

     private const string ROOT_DOCUMENT = "/Index.html";
    
    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        var path = Request.Url.AbsolutePath;
        var isApi = path.StartsWith("/api", StringComparison.InvariantCultureIgnoreCase);
        var isImageUpload = path.StartsWith("/home", StringComparison.InvariantCultureIgnoreCase);
    
        if (isApi || isImageUpload)
            return;
    
        string url = Request.Url.LocalPath;
        if (!System.IO.File.Exists(Context.Server.MapPath(url)))
            Context.RewritePath(ROOT_DOCUMENT);
    }
    
  5. Upewnij się, że używasz $location.url ('/XXX') a nie window.miejsce ... aby przekierować

  6. Odwołaj się do plików CSS ze ścieżką bezwzględną

I nie

<link href="app/content/bootstrapwc.css" rel="stylesheet" />

Ostatnia uwaga-robienie tego w ten sposób dało mi pełną kontrolę i nie musiałem nic robić z konfiguracją www.

Mam nadzieję, że to pomoże, bo trochę mi to zajęło.
 0
Author: tfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-07 15:15:55

Chciałem mieć dostęp do mojej aplikacji z trybem HTML5 i stałym tokenem, a następnie przełączyć się na metodę hashbang (aby zachować token, aby użytkownik mógł odświeżyć swoją stronę).

URL dostępu do mojej aplikacji:

http://myapp.com/amazing_url?token=super_token

Wtedy gdy użytkownik ładuje stronę:

http://myapp.com/amazing_url?token=super_token#/amazing_url

Wtedy gdy użytkownik przejdzie:

http://myapp.com/amazing_url?token=super_token#/another_url

Dzięki temu zachowuję token w adresie URL i zachowuję stan, gdy użytkownik przegląda. Straciłem trochę widoczności adresu URL, ale nie ma na to idealnego sposobu.

Więc nie włączaj trybu HTML5, a następnie dodaj ten kontroler:

.config ($stateProvider)->
    $stateProvider.state('home-loading', {
         url: '/',
         controller: 'homeController'
    })
.controller 'homeController', ($state, $location)->
    if window.location.pathname != '/'
        $location.url(window.location.pathname+window.location.search).replace()
    else
        $state.go('home', {}, { location: 'replace' })
 0
Author: Luc Boissaye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-09 19:58:20