Rimozione dell'identificatore di frammento dagli URL di AngularJS (simbolo #)


257

È possibile rimuovere il simbolo # dagli URL angular.js?

Voglio comunque essere in grado di utilizzare il pulsante Indietro del browser, ecc., Quando cambio la visualizzazione e aggiornerò l'URL con params, ma non voglio il simbolo #.

Il tutorial routeProvider viene dichiarato come segue:

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

Posso modificarlo per avere la stessa funzionalità senza #?


13
hashtag nice one
BoJack Horseman


Per me tutte le risposte qui sono sbagliate. Possiamo "riscrivere" l'URL e rimuovere il #, ma non accedere mai direttamente alla pagina web senza #. Qualche vera soluzione qui ???
amdev

Ecco la soluzione se stai usando Angular 1.6 .
Mistalis

Risposte:


252

Sì, è necessario configurare $locationProvidere insieme html5Modea 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);

  }]);

10
Perché IE lt 10 non supporta l'API cronologia html5 abilitata durante la configurazione html5Mode(true). In IE devi usare #nelle rotte.
Maxim Grach

10
@powtac IE lt 10significa Internet Explorer meno della versione 10
Maxim Grach

6
Puoi impostarlo in modo che questo fallisca nell'usare # in IE? E 'così semplice come avvolgere $locationProvider.html5Mode(true);in if !(IE lt 10)?
Andy Hayden

52
Quindi questa soluzione risolve la rimozione dell'hashtag nell'URL dato che l'URL ha un hashtag, tuttavia non risolve come rispondere alle richieste che non vogliono che l'hashtag sia incluso in primo luogo. Aka, risolve blah / # / telefoni -> blah / telefoni ma non gestisce direttamente blah / telefoni .
Luca

9
Dovevo mettere <base href = "/" /> nella mia sezione index.html <head>.
nyxz

56

Assicurati di controllare il supporto del browser per l'API della cronologia html5:

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }

23
Potrebbe essere più adatto come commento in quanto non risponde direttamente alla domanda.
brandonscript

31
Secondo la guida per sviluppatori , questo rilevamento viene eseguito automaticamente:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB

Ha funzionato alla perfezione e apprezzo il controllo del metodo piuttosto che il controllo della versione del browser: a prova di futuro.
Shane

46

Per rimuovere il tag hash per un URL carino e anche per far funzionare il codice dopo la minimizzazione, è necessario strutturare il codice come nell'esempio seguente:

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

15
Per il requireBase: false+1
whoan

2
Ciao @digitlimit, dopo aver aggiunto il $locationProvider.html5Modecodice il mio codice ha $urlRouterProvider.otherwise('/home');smesso di funzionare.
Jaikrat

18

Scrivo una regola in web.config dopo che $locationProvider.html5Mode(true)è stata impostata app.js.

Hope, aiuta qualcuno.

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

Nel mio index.html l'ho aggiunto a <head>

<base href="/">

Non dimenticare di installare il rewriter di URL per iis sul server.

Inoltre, se utilizzi Web Api e IIS, questo URL di corrispondenza non funzionerà, poiché cambierà le tue chiamate API. Quindi aggiungi il terzo input (terza riga di condizione) e dai un modello che escluderà le chiamate dawww.yourdomain.com/api


1
Come installi il rewriter di URL per IIS? Sto ospitando su Azure.
Prabhu

11

Se sei nello stack .NET con MVC con AngularJS, questo è ciò che devi fare per rimuovere il '#' dall'URL:

  1. Imposta il tuo href di base nella tua pagina _Layout: <head> <base href="https://stackoverflow.com/"> </head>

  2. Quindi, aggiungi quanto segue nella configurazione dell'app angolare: $locationProvider.html5Mode(true)

  3. Sopra rimuoverà '#' dall'URL ma l'aggiornamento della pagina non funzionerà ad es. Se sei in "yoursite.com/about" il refreash della pagina ti darà un 404. Questo perché MVC non conosce il routing angolare e secondo il pattern MVC lo cercherà una pagina MVC per "about" che non esiste nel percorso di instradamento MVC. La soluzione alternativa consiste nell'inviare tutte le richieste di pagine MVC a una singola vista MVC e puoi farlo aggiungendo un percorso che catturi tutto

url:

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);

Quale file devo aggiungere route.MapRoute?
Vicheanak

1
RouteConfig.cs si trova nella cartella
App_Start

5

Puoi modificare la modalità html5, ma è funzionale solo per i link inclusi negli ancoraggi html della tua pagina e per l'aspetto dell'URL nella barra degli indirizzi del browser. Il tentativo di richiedere una sottopagina senza l'hashtag (con o senza html5mode) da qualsiasi punto all'esterno della pagina risulterà in un errore 404. Ad esempio, la seguente richiesta CURL risulterà in un errore di pagina non trovata, indipendentemente dalla modalità html5:

$ curl http://foo.bar/phones

sebbene quanto segue restituirà la root / home page:

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

Il motivo è che qualsiasi cosa dopo l'hashtag viene rimossa prima che la richiesta arrivi al server. Quindi una richiesta di http://foo.bar/#/portfolioarriva al server come richiesta di http://foo.bar. Il server risponderà con una risposta 200 OK (presumibilmente) http://foo.bare l'agente / client elaborerà il resto.

Quindi, nei casi in cui desideri condividere un URL con altri, non hai altra scelta che includere l'hashtag.


Non c'è modo di aggirare questo? Questo è un grosso problema.
user441521

5

Segui 2 passaggi:
1. Per prima cosa imposta $ locationProvider.html5Mode (true) nel file di configurazione dell'app.
Ad esempio -
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2.In secondo luogo imposta la <base> nella tua pagina principale.
Ad esempio ->
<base href="https://stackoverflow.com/">

Il servizio $ location eseguirà automaticamente il fallback al metodo hash-part per i browser che non supportano l'API cronologia HTML5.


3

La mia soluzione è creare .htaccess e utilizzare il codice #Sorian .. senza .htaccess non sono riuscito a rimuovere #

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]

1

Secondo la documentazione. Puoi usare:

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

NB: Se il tuo browser non supporta HTML 5. Non preoccuparti: D ha fallback in modalità hashbang. Quindi, non è necessario controllare if(window.history && window.history.pushState){ ... }manualmente

Ad esempio: se fai clic su: <a href="https://stackoverflow.com/other">Some URL</a>

Nel browser HTML5 : angular reindirizzerà automaticamente aexample.com/other

Nel browser non HTML5 : angular reindirizzerà automaticamente aexample.com/#!/other


1

Questa risposta presuppone che tu stia utilizzando nginx come proxy inverso e che tu abbia già impostato $ locationProvider.html5mode su true.

-> Per le persone che potrebbero ancora essere alle prese con tutte le cose interessanti sopra.

Sicuramente, la soluzione @maxim grach funziona bene, ma per la soluzione su come rispondere alle richieste che non vogliono che l'hashtag sia incluso in primo luogo, quello che si può fare è controllare se php sta inviando 404 e quindi riscrivere l'url. Di seguito è riportato il codice per nginx,

Nella posizione php, rileva l'errore 404 php e reindirizza a un'altra posizione,

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

Quindi riscrivi l'URL nella posizione di reindirizzamento e proxy_pass i dati, fuori corso, metti l'URL del tuo sito web al posto dell'URL del mio blog. (Richiesta: interrogalo solo dopo averlo provato)

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

E guarda la magia.

E sicuramente funziona, almeno per me.


Dove aggiungerlo?
Volatil3

Dove aggiungere il codice sopra? Inseriscili nel file di configurazione principale di Nginx.
Satys

1

Inizia da index.html rimuovi tutto #da <a href="#/aboutus">About Us</a>quindi deve apparire come <a href="https://stackoverflow.com/aboutus">About Us</a>.Ora nel tag head di index.html scrivi <base href="https://stackoverflow.com/">subito dopo l'ultimo meta tag .

Ora nel tuo routing js inject $locationProvidere scrivi $locatonProvider.html5Mode(true); qualcosa di simile: -

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

Per maggiori dettagli guarda questo video https://www.youtube.com/watch?v=XsRugDQaGOo


La rimozione di tutti gli # URL ha aiutato perché lo stavo testando senza rimuovere #urls.
optimistanoop

1

Immagino che sia davvero tardi per questo. Ma l'aggiunta della configurazione seguente all'app.module imports fa il lavoro:

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

0

Passaggio 1: inserisci il servizio $ locationProvider nel costruttore della configurazione dell'app

Passaggio 2: aggiungi la riga di codice $ locationProvider.html5Mode (true) al costruttore della configurazione dell'app.

Passaggio 3: nella pagina del contenitore (destinazione, principale o layout), aggiungi un tag html come <base href="https://stackoverflow.com/">all'interno del tag.

Passaggio 4: rimuovi tutto "#" per la configurazione del routing da tutti i tag di ancoraggio. Ad esempio, href = "# home" diventa href = "home"; href = "# about" diventa herf = "about"; href = "# contact "diventa href =" contatto "

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

-1

Basta aggiungere $locationProviderIn

.config(function ($routeProvider,$locationProvider)

e poi aggiungi $locationProvider.hashPrefix(''); dopo

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

Questo è tutto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.