AngularJS-Routing ohne den Hash '#'


223

Ich lerne AngularJS und es gibt eine Sache, die mich wirklich nervt.

Ich $routeProviderdeklariere Routing-Regeln für meine Anwendung:

$routeProvider.when('/test', {
  controller: TestCtrl,
  templateUrl: 'views/test.html'
})
.otherwise({ redirectTo: '/test' });

aber wenn ich im Browser zu meiner App navigiere, sehe ich app/#/teststatt app/test.

Meine Frage ist also, warum AngularJS diesen Hash #zu URLs hinzufügt. Gibt es eine Möglichkeit, dies zu vermeiden?


2
Hier ist die Lösung, wenn Sie Angular 1.6 verwenden.
Mistalis

Antworten:


265

Tatsächlich benötigen Sie das # (Hashtag) für Nicht-HTML5-Browser.

Andernfalls führen sie nur einen HTTP-Aufruf an den Server an der angegebenen href durch. Das # ist ein alter Browser-Kurzschluss, der die Anforderung nicht auslöst, sodass viele js-Frameworks darüber hinaus ihre eigene clientseitige Umleitung erstellen können.

Sie können $locationProvider.html5Mode(true)Angular anweisen, die HTML5-Strategie zu verwenden, falls verfügbar.

Hier die Liste der Browser, die die HTML5-Strategie unterstützen: http://caniuse.com/#feat=history


4
OK danke. Das habe ich vermutet. Aber für mich ist das ziemlich benutzerunfreundlich! Angenommen, ich möchte, dass eine Ressource über URL, App / Res verfügbar ist. Wie können Benutzer meiner Website herausfinden, dass sie stattdessen app / # / res eingeben sollten?
Pikkvile

5
Aber wenn ja, warum müssen diese Pfade in der Positionsleiste sichtbar sein? Wenn Benutzer sie nicht verwenden, kann ich einfach eine einseitige Javascript-Anwendung erstellen.
Pikkvile

6
Dies ist nützlich, wenn Sie den Anwendungsstatus verfolgen möchten. Die Frameworks bieten einen Verlaufsmechanismus. Darüber hinaus ermöglicht es den direkten Zugriff auf einen Status Ihrer Anwendung zum Beispiel über URL-Sharing
plus

6
Das Hashtag ist in modernen Browsern, die die HTML5-Verlaufs-API unterstützen, nicht erforderlich. Siehe die Antwort von @ skeep und die bereitgestellten Links. Im HTML5-Modus verwendet Angular nur Hashtags, wenn der Browser dies nicht unterstützt. Beachten Sie auch, dass Sie $ routeProvider nicht verwenden müssen, wenn Sie nicht möchten ... Sie können Ihr eigenes Routing mit ng-clicks und ng-include verkabeln (tatsächlich müssen Sie dies tun, wenn Sie mehrere Ebenen von benötigen Routing, da ng-view nur einmal pro Seite angezeigt werden kann). Siehe auch stackoverflow.com/questions/12793609/…
Mark Rajcok

2
Für den Fall Hashbang / Pushstate / Server-Side-Rendering-HTML ist der Twitter-Fall ziemlich gut zu lesen. Engineering.twitter.com/2012/12/… Es wird erklärt, wie sie es geschafft haben, damit er abwärtskompatibel mit dem alten Browser und mit der Suche ist Motoren. Ich weiß, dass es nicht eckig ist, aber Sie können den Fluss reproduzieren.
Jackdbernier

47

Wenn Sie html5mode aktiviert haben, wie andere gesagt haben, und eine .htaccessDatei mit dem folgenden Inhalt erstellen (an Ihre Bedürfnisse anpassen):

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]

Benutzer werden zu Ihrer App weitergeleitet, wenn sie eine richtige Route eingeben, und Ihre App liest die Route und bringt sie auf die richtige "Seite" darin.

BEARBEITEN: Stellen Sie nur sicher, dass keine Datei- oder Verzeichnisnamen mit Ihren Routen in Konflikt stehen.


Gibt es eine Nginx-Version davon? Wenn ich lade, /aboutschlägt die Seite fehl, es sei denn, ich komme über die App dazu.
Chovy

Ich habe sie nie benutzt, aber versuche dies: stackoverflow.com/questions/5840497/convert-htaccess-to-nginx
bearfriend

3
@chovy - hier geht die nGinx-Version: server {Servername my-app; root / path / to / app; location / {try_files $ uri $ uri / /index.html; }}
Moin Haidar

4
Denken Sie daran, <base href = "/"> </ base> in head tag
Silvio Troia

Vielen Dank! Ohne dies ist eine tiefe Verknüpfung nicht möglich. Ich bin mir immer noch nicht sicher, ob die Schönheit oder die URIs die Mühe wert sind, diese beizubehalten, wenn Sie Deep Linking benötigen, insbesondere in einigen Cloud / Paas-Umgebungen, in denen Sie möglicherweise keinen einfachen Zugriff auf httpd config haben.
Pierre Henry

39

Schreiben wir eine Antwort, die einfach und kurz aussieht

Fügen Sie im Router am Ende html5Mode (true) hinzu .

app.config(function($routeProvider,$locationProvider) {

    $routeProvider.when('/home', {
        templateUrl:'/html/home.html'
    });

    $locationProvider.html5Mode(true);
})

Fügen Sie im HTML-Kopf das Basis- Tag hinzu

<html>
<head>
    <meta charset="utf-8">    
    <base href="/">
</head>

Vielen Dank an @plus - für die Detaillierung der obigen Antwort


Ich habe es nicht geschafft, dies zum Laufen zu bringen. Ich habe eine neue Frage mit meinen spezifischen Daten veröffentlicht unter: stackoverflow.com/questions/36041074/… Bitte schauen Sie sich diese an und wenn Sie helfen können, würde ich mich sehr darüber freuen.
Larry Martell

30

Versuchen

$locationProvider.html5Mode(true)

Weitere Informationen unter $ locationProvider
Verwenden von $ location


6
Entschuldigung, ich habe .config (Funktion ($ locationProvider) {$ locationProvider.html5Mode (true)}) hinzugefügt, aber ich habe das Ergebnis index.html #% 2Fhome not index.html / home
zloctb

12

Die folgenden Informationen stammen von:
https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag

Es ist sehr einfach, saubere URLs abzurufen und das Hashtag aus der URL in Angular zu entfernen.
Standardmäßig leitet AngularJS URLs mit einem Hashtag weiter. Beispiel:

Es gibt zwei Dinge, die getan werden müssen.

  • $ LocationProvider konfigurieren

  • Festlegen unserer Basis für relative Links

  • $ location Service

In Angular analysiert der $ location-Dienst die URL in der Adressleiste und nimmt Änderungen an Ihrer Anwendung vor und umgekehrt.

Ich würde wärmstens empfehlen, die offiziellen Angular $ -Standortdokumente zu lesen, um ein Gefühl für den Standortdienst und dessen Angebot zu bekommen.

https://docs.angularjs.org/api/ng/service/$location

$ locationProvider und html5Mode

  • Wir werden das $ locationProvider-Modul verwenden und html5Mode auf true setzen.
  • Wir werden dies tun, wenn Sie Ihre Angular-Anwendung definieren und Ihre Routen konfigurieren.

    angular.module('noHash', [])
    
    .config(function($routeProvider, $locationProvider) {
    
       $routeProvider
           .when('/', {
               templateUrl : 'partials/home.html',
               controller : mainController
           })
           .when('/about', {
               templateUrl : 'partials/about.html',
               controller : mainController
           })
           .when('/contact', {
               templateUrl : 'partials/contact.html',
               controller : mainController
           });
    
       // use the HTML5 History API
       $locationProvider.html5Mode(true); });

Was ist die HTML5-Verlaufs-API? Es ist eine standardisierte Methode, um den Browserverlauf mithilfe eines Skripts zu bearbeiten. Dadurch kann Angular das Routing und die URLs unserer Seiten ändern, ohne die Seite zu aktualisieren. Weitere Informationen hierzu finden Sie in einem guten Artikel zur HTML5-Verlaufs-API:

http://diveintohtml5.info/history.html

Einstellung für relative Links

  • Um Ihre Anwendung mithilfe relativer Links zu verknüpfen, müssen Sie die <base>in <head>Ihrem Dokument festlegen . Dies kann sich in der Datei root index.html Ihrer Angular-App befinden. Suchen Sie das <base>Tag und setzen Sie es auf die Stamm-URL, die Sie für Ihre App möchten.

Beispielsweise: <base href="https://stackoverflow.com/">

  • Es gibt viele andere Möglichkeiten, dies zu konfigurieren, und der auf true eingestellte HTML5-Modus sollte relative Links automatisch auflösen. Wenn sich Ihr Stammverzeichnis Ihrer Anwendung von der URL unterscheidet (z. B. / my-base), verwenden Sie diese als Basis.

Fallback für ältere Browser

  • Der $ location-Dienst greift automatisch auf die Hashbang-Methode für Browser zurück, die die HTML5-Verlaufs-API nicht unterstützen.
  • Dies geschieht transparent für Sie und Sie müssen nichts konfigurieren, damit es funktioniert. In den Angular $ location-Dokumenten können Sie die Fallback-Methode und ihre Funktionsweise sehen.

Abschließend

  • Dies ist eine einfache Möglichkeit, hübsche URLs abzurufen und das Hashtag in Ihrer Angular-Anwendung zu entfernen. Viel Spaß beim Erstellen dieser super sauberen und superschnellen Angular-Apps!

3

Wenn Sie dies lokal unter OS X 10.8 konfigurieren möchten, das Angular mit Apache bereitstellt, finden Sie möglicherweise folgende Hilfen in Ihrer .htaccess-Datei:

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On
    RewriteBase /~yourusername/appname/public/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !.*\.(css|js|html|png|jpg|jpeg|gif|txt)
    RewriteRule (.*) index.html [L]
</IfModule>

Optionen + FollowSymlinks, falls nicht festgelegt, können zu einem verbotenen Fehler in den Protokollen führen:

Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden

Eine Umschreibbasis ist erforderlich, andernfalls werden Anforderungen an Ihren Serverstamm aufgelöst, der lokal standardmäßig nicht Ihr Projektverzeichnis ist, es sei denn, Sie haben Ihre vhosts speziell konfiguriert. Daher müssen Sie den Pfad so festlegen, dass die Anforderung Ihr Projektstammverzeichnis findet. Zum Beispiel habe ich auf meinem Computer ein Verzeichnis / Users / me / Sites, in dem ich alle meine Projekte aufbewahre. Wie das alte OS X eingerichtet.

In den nächsten beiden Zeilen wird effektiv angegeben, ob der Pfad kein Verzeichnis oder keine Datei ist. Sie müssen daher sicherstellen, dass Sie keine Dateien oder Verzeichnisse haben, die mit den Routenpfaden Ihrer App identisch sind.

Die nächste Bedingung lautet: Wenn die Anforderung nicht mit den angegebenen Dateierweiterungen endet, fügen Sie dort das hinzu, was Sie benötigen

Und das letzte [L] sagt, dass es die Datei index.html bereitstellen soll - Ihre App für alle anderen Anforderungen.

Wenn Sie immer noch Probleme haben, überprüfen Sie das Apache-Protokoll. Es gibt Ihnen wahrscheinlich nützliche Hinweise:

/private/var/log/apache2/error_log

Wenn Sie MAMP als Ihren lokalen Host-Apache-Server verwenden, stellen Sie sicher, dass die erste RewriteBase ein relativer Link ist. zB RewriteBase / anglejs_site_folder /
David Douglas

3

Im HTML5-Modus muss die URL auf der Serverseite neu geschrieben werden. Grundsätzlich müssen Sie alle Links zum Einstiegspunkt Ihrer Anwendung (z. B. index.html) neu schreiben. Das Erfordernis eines <base>Tags ist auch in diesem Fall wichtig, da AngularJS damit zwischen dem Teil der URL, der die Anwendungsbasis darstellt, und dem Pfad unterscheiden kann, der von der Anwendung verarbeitet werden soll. Weitere Informationen finden Sie im AngularJS-Entwicklerhandbuch - Verwenden des HTML5-Modus im Server von $ location Server Side .


Aktualisieren

Gewusst wie: Konfigurieren Sie Ihren Server für die Arbeit mit html5Mode 1

Wenn Sie html5Mode aktiviert haben, wird das #Zeichen in Ihren URLs nicht mehr verwendet. Das #Symbol ist nützlich, da keine serverseitige Konfiguration erforderlich ist. Ohne #sieht die URL viel besser aus, erfordert aber auch serverseitige Umschreibungen. Hier sind einige Beispiele:

Apache schreibt um

<VirtualHost *:80>
    ServerName my-app

    DocumentRoot /path/to/app

    <Directory /path/to/app>
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html to allow html5 state links
        RewriteRule ^ index.html [L]
    </Directory>
</VirtualHost>

Nginx schreibt um

server {
    server_name my-app;

    index index.html;

    root /path/to/app;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Azure IIS-Umschreibungen

<system.webServer>
  <rewrite>
    <rules> 
      <rule name="Main Rule" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="/" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

Express-Umschreibungen

var express = require('express');
var app = express();

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));

app.all('/*', function(req, res, next) {
    // Just send the index.html for other files to support HTML5Mode
    res.sendFile('index.html', { root: __dirname });
});

app.listen(3006); //the port you want to use

Siehe auch


1

In Angular 6 können Sie mit Ihrem Router Folgendes verwenden:

RouterModule.forRoot(routes, { useHash: false })

0

Sie können auch den folgenden Code verwenden, um zur Hauptseite (Startseite) umzuleiten:

{ path: '', redirectTo: 'home', pathMatch: 'full'}

Nachdem Sie Ihre Weiterleitung wie oben angegeben haben, können Sie die anderen Seiten umleiten, zum Beispiel:

{ path: 'add-new-registration', component: AddNewRegistrationComponent},
{ path: 'view-registration', component: ViewRegistrationComponent},
{ path: 'home', component: HomeComponent}

0

** **.

Es wird empfohlen, den HTML 5-Stil (PathLocationStrategy) als Standortstrategie in Angular zu verwenden

** Weil

  1. Es werden saubere und SEO-freundliche URLs erstellt, die für Benutzer leichter zu verstehen und zu merken sind.
  2. Sie können das serverseitige Rendern nutzen, wodurch unsere Anwendung schneller geladen wird, indem Sie zuerst die Seiten auf dem Server rendern, bevor Sie sie an den Client senden.

Verwenden Sie Hashlocationstrtegy nur, wenn Sie die älteren Browser unterstützen müssen.

Klicken Sie hier, um mehr zu erfahren

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.