Usuwanie identyfikatora fragmentu z adresów URL AngularJS (symbol #)

257

Czy można usunąć symbol # z adresów URL angular.js?

Nadal chcę mieć możliwość korzystania z przycisku Wstecz przeglądarki itp. Po zmianie widoku i zaktualizowaniu adresu URL za pomocą parametrów, ale nie chcę symbolu #.

Samouczek routeProvider jest zadeklarowany w następujący sposób:

angular.module('phonecat', []).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
  when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
  when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
  otherwise({redirectTo: '/phones'});
}]);

Czy mogę to edytować, aby mieć tę samą funkcjonalność bez #?

Tim Webster
źródło
13
hashtag nice one
BoJack Horseman
Dla mnie wszystkie odpowiedzi tutaj są błędne. Możemy „przepisać” adres URL i usunąć #, ale nigdy nie uzyskujemy bezpośredniego dostępu do strony bez #. Jakieś prawdziwe rozwiązanie tutaj?
amdev
Oto rozwiązanie, jeśli używasz Angulara 1.6 .
Mistalis

Odpowiedzi:

251

Tak, powinieneś skonfigurować $locationProvideri ustawić html5Modena true:

angular.module('phonecat', []).
  config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {

    $routeProvider.
      when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});

    $locationProvider.html5Mode(true);

  }]);
Maxim Grach
źródło
10
Ponieważ IE lt 10 nie obsługuje interfejsu API historii HTML5, które zostały włączone podczas konfiguracji html5Mode(true). W IE musisz używać #na trasach.
Maxim Grach
10
@powtac IE lt 10oznacza Internet Explorera w wersji mniejszej niż 10
Maxim Grach
6
Czy możesz to ustawić tak, aby cofał się do używania # w IE? Jest to tak proste, jak tylko owijania $locationProvider.html5Mode(true);w if !(IE lt 10)?
Andy Hayden
52
Więc to rozwiązanie rozwiązuje problem usuwania hashtagu z adresu URL, biorąc pod uwagę, że adres URL ma hashtag, jednak nie rozwiązuje tego, jak odpowiedzieć na żądania, które nie chcą, aby hashtag był w ogóle uwzględniony. Ok, rozwiązuje bla / # / telefony -> bla / telefony, ale nie obsługuje bezpośrednio bla / telefonów .
Łukasz
9
Musiałem umieścić <base href = "/" /> w mojej sekcji index.html <head>.
nyxz,
55

Sprawdź obsługę przeglądarki dla interfejsu API historii HTML5:

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }
SSaidi
źródło
23
Może to być lepiej dostosowane jako komentarz, ponieważ nie odpowiada bezpośrednio na pytanie.
brandonscript
31
Zgodnie z podręcznikiem programisty wykrywanie odbywa się automatycznie:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB
Działało to jak urok i doceniam sprawdzanie metod zamiast sprawdzania wersji przeglądarki - na przyszłość.
Shane
46

Aby usunąć znacznik skrótu dla ładnego adresu URL, a także aby Twój kod działał po zminimalizowaniu , musisz ustrukturyzować swój kod, jak na poniższym przykładzie:

jobApp.config(['$routeProvider','$locationProvider',
    function($routeProvider, $locationProvider) {
        $routeProvider.
            when('/', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus/:id', {
                templateUrl: 'views/job-detail.html',
                controller: 'JobDetailController'
            });

         //you can include a fallback by  including .otherwise({
          //redirectTo: '/jobs'
        //});


        //check browser support
        if(window.history && window.history.pushState){
            //$locationProvider.html5Mode(true); will cause an error $location in HTML5 mode requires a  tag to be present! Unless you set baseUrl tag after head tag like so: <head> <base href="https://stackoverflow.com/">

         // to know more about setting base URL visit: https://docs.angularjs.org/error/$location/nobase

         // if you don't wish to set base URL then use this
         $locationProvider.html5Mode({
                 enabled: true,
                 requireBase: false
          });
        }
    }]);
Emeka Mbah
źródło
15
Dla requireBase: false+1
whoan
2
Witaj @digitlimit, Po dodaniu $locationProvider.html5Modekodu mój kod $urlRouterProvider.otherwise('/home');przestał działać.
Jaikrat
18

Zapisuję regułę w pliku web.config po $locationProvider.html5Mode(true)ustawieniu w app.js.

Mam nadzieję, że ktoś pomaga.

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

W moim index.html dodałem to do <head>

<base href="/">

Nie zapomnij zainstalować przepisywania adresu URL dla iis na serwerze.

Również w przypadku korzystania z interfejsu API sieci Web i usług IIS ten adres URL nie zadziała, ponieważ zmieni połączenia w interfejsie API. Dodaj więc trzecie wejście (trzecia linia warunku) i podaj wzór, który wyklucza połączenia zwww.yourdomain.com/api

Yagiz Ozturk
źródło
1
Jak zainstalować program do przepisywania adresów URL dla IIS? Hostuję na platformie Azure.
Prabhu
11

Jeśli jesteś w stosie .NET z MVC z AngularJS, musisz to zrobić, aby usunąć „#” z adresu URL:

  1. Skonfiguruj swój podstawowy href na stronie _Layout: <head> <base href="https://stackoverflow.com/"> </head>

  2. Następnie dodaj następujące elementy w konfiguracji aplikacji kątowej: $locationProvider.html5Mode(true)

  3. Powyżej usunie „#” z adresu URL, ale odświeżanie strony nie będzie działać, np. Jeśli jesteś w „yoursite.com/about” ponowne odświeżenie strony da ci 404. Jest tak, ponieważ MVC nie wie o routingu kątowym i według wzoru MVC wyszuka stronę MVC dla „about”, która nie istnieje w ścieżce routingu MVC. Obejściem tego problemu jest wysłanie całego żądania strony MVC do pojedynczego widoku MVC. Można to zrobić, dodając trasę, która przechwytuje wszystkie

URL:

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);
Maksood
źródło
Który plik powinienem dodać trasy.MapRoute?
Vicheanak
1
RouteConfig.cs znajduje się w folderze
App_Start
5

Możesz dostosować tryb html5, ale działa to tylko w przypadku linków zawartych w kotwicach html strony i jak wygląda adres URL w pasku adresu przeglądarki. Próba zażądania podstrony bez hashtagu (z trybem html5 lub bez) z dowolnego miejsca poza stroną spowoduje błąd 404. Na przykład następujące żądanie CURL spowoduje błąd znalezienia strony, niezależnie od trybu html5:

$ curl http://foo.bar/phones

chociaż następujące spowoduje zwrócenie strony głównej / głównej:

$ curl http://foo.bar/#/phones

Powodem tego jest to, że wszystko po usunięciu hashtagu, zanim żądanie dotrze do serwera. Tak więc żądanie http://foo.bar/#/portfolioprzychodzi na serwer jako żądanie http://foo.bar. Serwer odpowie 200 odpowiedziami OK (prawdopodobnie) nahttp://foo.bar a agent / klient przetworzy resztę.

Dlatego w przypadkach, gdy chcesz udostępnić adres URL innym osobom, nie masz innej opcji, jak dołączyć hashtag.

Chris
źródło
Czy nie można tego obejść? To dość duży problem.
user441521,
5

Wykonaj 2 kroki -
1. Najpierw ustaw $ locationProvider.html5Mode (true) w pliku konfiguracyjnym aplikacji.
Na przykład -
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2. Po drugie ustaw <base> na swojej stronie głównej.
Na przykład ->
<base href="https://stackoverflow.com/">

Usługa lokalizacji $ automatycznie powróci do metody części mieszającej dla przeglądarek, które nie obsługują interfejsu API historii HTML5.

Anshul Bisht
źródło
3

Moje rozwiązanie polega na utworzeniu .htaccess i użyciu #Sorian code .. bez .htaccess Nie udało mi się usunąć #

RewriteEngine   On
RewriteBase     /
RewriteCond     %{REQUEST_URI} !^(/index\.php|/img|/js|/css|/robots\.txt|/favicon\.ico)
RewriteCond     %{REQUEST_FILENAME} !-f
RewriteCond     %{REQUEST_FILENAME} !-d
RewriteRule     ./index.html [L]
Thomas Knápek
źródło
1

Zgodnie z dokumentacją. Możesz użyć:

$locationProvider.html5Mode(true).hashPrefix('!');

Uwaga: jeśli twoja przeglądarka nie obsługuje HTML 5. Nie martw się: D ma tryb awaryjny w trybie hashbang. Nie musisz więc sprawdzać if(window.history && window.history.pushState){ ... }ręcznie

Na przykład: jeśli klikniesz: <a href="https://stackoverflow.com/other">Some URL</a>

W przeglądarce HTML5 : angular automatycznie przekieruje doexample.com/other

W przeglądarce innej niż HTML5 : angular automatycznie przekieruje doexample.com/#!/other

Efriandika Pratama
źródło
1

Ta odpowiedź zakłada, że ​​używasz nginx jako odwrotnego proxy i już ustawiłeś $ locationProvider.html5mode na true.

-> Dla ludzi, którzy wciąż mogą zmagać się ze wszystkimi fajnymi rzeczami powyżej.

Z pewnością @maxim gry rozwiązanie działa dobrze, ale dla rozwiązania, w jaki sposób odpowiadać na żądania, które nie chcą, aby hashtag był uwzględniony w pierwszej kolejności, można sprawdzić, czy php wysyła 404, a następnie przepisać adres URL. Poniżej znajduje się kod dla nginx,

W lokalizacji php wykryj błąd 404 php i przekieruj do innej lokalizacji,

location ~ \.php${
  ...
  fastcgi_intercept_errors on;
  error_page 404 = /redirect/$request_uri ;
}

Następnie przepisz adres URL w lokalizacji przekierowania i proxy_pass the data, offcourse, umieść adres swojej witryny w miejscu adresu URL mojego bloga. (Żądanie: Pytanie to dopiero po wypróbowaniu)

location /redirect {
  rewrite ^/redirect/(.*) /$1;
  proxy_pass http://www.techromance.com;
}

I zobacz magię.

I to na pewno działa, przynajmniej dla mnie.

Satys
źródło
Gdzie to dodać?
Volatil3
Gdzie dodać powyższy kod? Umieść je w głównym pliku konfiguracyjnym Nginx.
Satys,
1

Zacznij od index.html usuń wszystko #z, <a href="#/aboutus">About Us</a>więc musi wyglądać jak <a href="https://stackoverflow.com/aboutus">About Us</a>.Now w tagu head index.html napisz <base href="https://stackoverflow.com/">tuż po ostatnim metatagu .

Teraz w swoim routingu js wstrzykuje $locationProvideri pisze $locatonProvider.html5Mode(true); coś takiego: -

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when("/home", {
            templateUrl: "Templates/home.html",
            controller: "homeController"
        })
            .when("/aboutus",{templateUrl:"Templates/aboutus.html"})
            .when("/courses", {
                templateUrl: "Templates/courses.html",
                controller: "coursesController"
            })
            .when("/students", {
                templateUrl: "Templates/students.html",
                controller: "studentsController"
            })
        $locationProvider.html5Mode(true);
    });

Aby uzyskać więcej informacji, obejrzyj ten film https://www.youtube.com/watch?v=XsRugDQaGOo

Aniket Jha
źródło
Usunięcie wszystkich # Url pomogło, ponieważ testowałem je bez usuwania #urls.
optimistanoop
1

Domyślam się, że jest na to naprawdę spóźniony. Ale dodanie poniższej konfiguracji do importu app.module wykonuje zadanie:

RouterModule.forRoot(routes, { useHash: false })
Sagar Bhat
źródło
0

Krok 1: Wstrzyknij usługę $ locationProvider do konstruktora konfiguracji aplikacji

Krok 2: Dodaj wiersz kodu $ locationProvider.html5Mode (true) do konstruktora konfiguracji aplikacji.

Krok 3: na stronie kontenera (lądowanie, wzorzec lub układ) dodaj znacznik HTML, taki jak <base href="https://stackoverflow.com/">wewnątrz znacznika.

Krok 4: usuń wszystkie „#” do konfiguracji routingu ze wszystkich tagów zakotwiczenia. Na przykład href = "# home" staje się href = "home"; href = "# about" staje się herf = "about"; href = "# contact „staje się href =„ kontakt ”

 <ul class="nav navbar-nav">
     <li><a href="home">Home</a></li>
     <li><a href="about">About us</a></li>
     <li><a href="contact">Contact us</a></li>
</ul>
Thomas.Benz
źródło
-1

Wystarczy dodać $locationProviderIn

.config(function ($routeProvider,$locationProvider)

a następnie dodaj $locationProvider.hashPrefix(''); po

.otherwise({
        redirectTo: '/'
      });

Otóż ​​to.

Narendra Solanki
źródło