Entfernen der Fragmentkennung aus AngularJS-URLs (# -Symbol)

257

Ist es möglich, das Symbol # aus den URLs von angle.js zu entfernen?

Ich möchte weiterhin die Zurück-Schaltfläche des Browsers usw. verwenden können, wenn ich die Ansicht ändere und die URL mit Parametern aktualisiere, aber ich möchte nicht das # -Symbol.

Das Tutorial routeProvider wird wie folgt deklariert:

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'});
}]);

Kann ich dies bearbeiten, um die gleiche Funktionalität ohne das # zu haben?

Tim Webster
quelle
13
Hashtag schön
BoJack Horseman
Für mich sind alle Antworten hier falsch. Wir können die URL "umschreiben" und das # entfernen, aber niemals ohne # direkt auf die Webseite zugreifen. Irgendeine echte Lösung hier ???
Amdev
Hier ist die Lösung, wenn Sie Angular 1.6 verwenden .
Mistalis

Antworten:

251

Ja, Sie sollten konfigurieren $locationProviderund einstellen html5Modeauf 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
quelle
10
Weil IE lt 10 keine HTML5-Verlaufs-API unterstützt, die durch das Einrichten aktiviert wurde html5Mode(true). Im IE müssen Sie #in Routen verwenden.
Maxim Grach
10
@powtac IE lt 10bedeutet Internet Explorer weniger als Version 10
Maxim Grach
6
Können Sie es so einstellen, dass dies auf die Verwendung von # im IE zurückgreift? Ist es so einfach wie nur Einwickeln $locationProvider.html5Mode(true);in if !(IE lt 10)?
Andy Hayden
52
Diese Lösung löst also das Entfernen des Hashtags in der URL, da die URL ein Hashtag enthält. Sie löst jedoch nicht, wie auf Anforderungen reagiert werden soll, bei denen das Hashtag überhaupt nicht enthalten sein soll. Aka, es löst bla / # / Telefone -> bla / Telefone, aber es behandelt bla / Telefone nicht direkt.
Luke
9
Ich musste <base href = "/" /> in meinen Abschnitt index.html <head> einfügen.
Nyxz
55

Überprüfen Sie unbedingt die Browserunterstützung für die HTML5-Verlaufs-API:

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }
SSaidi
quelle
23
Dies ist möglicherweise besser als Kommentar geeignet, da die Frage nicht direkt beantwortet wird.
Brandonscript
31
Laut Entwicklerhandbuch erfolgt diese Erkennung automatisch:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB
Hat wie ein Zauber funktioniert, und ich schätze eher die Methodenprüfung als die Überprüfung der Browserversion - zukunftssicher.
Shane
46

Um das Hash-Tag für eine hübsche URL zu entfernen und damit Ihr Code nach der Minimierung funktioniert , müssen Sie Ihren Code wie im folgenden Beispiel strukturieren:

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
quelle
15
Für die requireBase: false+1
whoan
2
Hallo @digitlimit, nach dem Hinzufügen von $locationProvider.html5ModeCode $urlRouterProvider.otherwise('/home');funktionierte mein Code nicht mehr.
Jaikrat
18

Ich schreibe eine Regel in web.config, nachdem sie $locationProvider.html5Mode(true)eingestellt wurde app.js.

Hoffe, hilft jemandem aus.

  <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>

In meiner index.html habe ich dies hinzugefügt <head>

<base href="/">

Vergessen Sie nicht, URL Rewriter für iis auf dem Server zu installieren.

Auch wenn Sie Web-API und IIS verwenden, funktioniert diese Übereinstimmungs-URL nicht, da sie Ihre API-Aufrufe ändert. Fügen Sie also die dritte Eingabe (dritte Bedingungszeile) hinzu und geben Sie ein Muster aus, von dem Anrufe ausgeschlossen werdenwww.yourdomain.com/api

Yagiz Ozturk
quelle
1
Wie installiere ich URL Rewriter für IIS? Ich hoste auf Azure.
Prabhu
11

Wenn Sie sich im .NET-Stack mit MVC mit AngularJS befinden, müssen Sie Folgendes tun, um das '#' aus der URL zu entfernen:

  1. Richten Sie Ihre Basis-HREF auf Ihrer _Layout-Seite ein: <head> <base href="https://stackoverflow.com/"> </head>

  2. Fügen Sie dann Folgendes in Ihre eckige App-Konfiguration ein: $locationProvider.html5Mode(true)

  3. Oben wird '#' aus der URL entfernt, aber die Seitenaktualisierung funktioniert nicht, z. B. wenn Sie sich auf der Seite "yoursite.com/about" befinden. Refreash gibt Ihnen eine 404. Dies liegt daran, dass MVC das Winkelrouting und das MVC-Muster nicht kennt sucht nach einer MVC-Seite für 'about', die im MVC-Routing-Pfad nicht vorhanden ist. Um dieses Problem zu umgehen, senden Sie alle MVC-Seitenanforderungen an eine einzelne MVC-Ansicht. Sie können dies tun, indem Sie eine Route hinzufügen, die alle abfängt

URL:

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);
Maksood
quelle
Welche Datei soll ich die route.MapRoute hinzufügen?
Vicheanak
1
RouteConfig.cs ist unter App_Start Ordner
Maksood
5

Sie können den HTML5-Modus optimieren, dies funktioniert jedoch nur für Links, die in HTML-Ankern Ihrer Seite enthalten sind und wie die URL in der Adressleiste des Browsers aussieht. Der Versuch, eine Unterseite ohne Hashtag (mit oder ohne html5mode) von einer beliebigen Stelle außerhalb der Seite anzufordern, führt zu einem 404-Fehler. Beispielsweise führt die folgende CURL-Anforderung unabhängig vom HTML5-Modus zu einem Fehler, bei dem die Seite nicht gefunden wurde:

$ curl http://foo.bar/phones

obwohl das Folgende die Stamm- / Homepage zurückgibt:

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

Der Grund dafür ist, dass alles, was nach dem Hashtag entfernt wurde, bevor die Anforderung auf dem Server eintrifft. Eine Anfrage für http://foo.bar/#/portfoliokommt also als Anfrage für auf dem Server an http://foo.bar. Der Server antwortet (vermutlich) mit 200 OK http://foo.barund der Agent / Client verarbeitet den Rest.

In Fällen, in denen Sie eine URL mit anderen teilen möchten, haben Sie keine andere Wahl, als das Hashtag einzuschließen.

chris
quelle
Gibt es keinen Weg daran vorbei? Dies ist ein ziemlich großes Problem.
user441521
5

Befolgen Sie zwei Schritte:
1. Legen Sie zuerst den $ locationProvider.html5Mode (true) in Ihrer App-Konfigurationsdatei fest.
Zum Beispiel -
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2.Setzen Sie die <Basis> auf Ihrer Hauptseite.
Zum Beispiel ->
<base href="https://stackoverflow.com/">

Der $ location-Dienst greift automatisch auf die Hash-Part-Methode für Browser zurück, die die HTML5-Verlaufs-API nicht unterstützen.

Anshul Bisht
quelle
3

Meine Lösung besteht darin, .htaccess zu erstellen und # Sorian-Code zu verwenden. Ohne .htaccess konnte ich # nicht entfernen.

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
quelle
1

Laut Dokumentation. Sie können verwenden:

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

NB: Wenn Ihr Browser HTML 5 nicht unterstützt. Keine Sorge: D Er hat einen Fallback auf den Hashbang-Modus. Sie müssen also nicht if(window.history && window.history.pushState){ ... }manuell nachfragen

Zum Beispiel: Wenn Sie klicken auf: <a href="https://stackoverflow.com/other">Some URL</a>

Im HTML5-Browser : Angular leitet automatisch zu weiterexample.com/other

In Not HTML5 Browser : Angular leitet automatisch zu weiterexample.com/#!/other

Efriandika Pratama
quelle
1

Bei dieser Antwort wird davon ausgegangen, dass Sie nginx als Reverse-Proxy verwenden und $ locationProvider.html5mode bereits auf true gesetzt haben.

-> Für die Leute, die immer noch mit all den coolen Sachen oben zu kämpfen haben.

Sicherlich funktioniert die @ maxim-Grach-Lösung einwandfrei, aber für die Lösung, wie auf Anfragen reagiert werden soll, bei denen das Hashtag überhaupt nicht enthalten sein soll, müssen Sie überprüfen, ob PHP 404 sendet, und dann die URL neu schreiben. Es folgt der Code für Nginx:

Erkennen Sie am PHP-Speicherort einen 404-PHP-Fehler und leiten Sie ihn an einen anderen Speicherort weiter.

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

Schreiben Sie dann die URL an der Umleitungsposition neu und geben Sie die Daten an proxy_pass weiter. Setzen Sie die URL Ihrer Website an die Stelle der URL meines Blogs. (Anfrage: Frage dies erst, nachdem du es versucht hast)

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

Und sieh die Magie.

Und es funktioniert definitiv, zumindest für mich.

Satys
quelle
Wo soll man das hinzufügen?
Volatil3
Wo kann man den obigen Code hinzufügen? Fügen Sie sie in die Hauptkonfigurationsdatei von Nginx ein.
Satys
1

Beginnen Sie mit index.html. Entfernen Sie alles #aus, <a href="#/aboutus">About Us</a>damit es wie <a href="https://stackoverflow.com/aboutus">About Us</a>folgt aussieht. Schreiben Sie jetzt im head-Tag von index.html <base href="https://stackoverflow.com/">direkt nach dem letzten Meta-Tag .

Jetzt in Ihr Routing js injizieren $locationProviderund schreiben Sie so $locatonProvider.html5Mode(true); etwas: -

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);
    });

Weitere Details finden Sie in diesem Video unter https://www.youtube.com/watch?v=XsRugDQaGOo

Aniket Jha
quelle
Das Entfernen aller # URLs hat geholfen, weil ich es getestet habe, ohne #urls zu entfernen.
Optimistanoop
1

Ich denke, das ist wirklich spät dafür. Das Hinzufügen der folgenden Konfiguration zu den app.module-Importen erledigt jedoch die Aufgabe:

RouterModule.forRoot(routes, { useHash: false })
Sagar Bhat
quelle
0

Schritt 1: Injizieren Sie den Dienst $ locationProvider in den Konstruktor der App-Konfiguration

Schritt 2: Fügen Sie dem Konstruktor der App-Konfiguration die Codezeile $ locationProvider.html5Mode (true) hinzu.

Schritt 3: Fügen Sie auf der Containerseite (Landing, Master oder Layout) ein HTML-Tag hinzu, z. B. <base href="https://stackoverflow.com/">innerhalb des Tags.

Schritt 4: Entfernen Sie alle '# "für das Routing der Konfiguration von allen Ankertags. Beispielsweise wird href =" # home "zu href =" home "; href =" # about "wird zu herf =" about "; href =" # contact "wird 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
quelle
-1

Fügen Sie einfach $locationProviderin

.config(function ($routeProvider,$locationProvider)

und dann $locationProvider.hashPrefix(''); nach hinzufügen

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

Das ist es.

Narendra Solanki
quelle