$ 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.
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
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ę..
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
- Dodaj do indeksu.html - base href="/">
-
Dodaj $ locationProvider.html5Mode (true); do aplikacji.config
-
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" } );
-
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); }
-
Upewnij się, że używasz $location.url ('/XXX') a nie window.miejsce ... aby przekierować
-
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.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' })
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