Suppression de l'identifiant de fragment des URL AngularJS (symbole #)


257

Est-il possible de supprimer le symbole # des URL angular.js?

Je veux toujours pouvoir utiliser le bouton de retour du navigateur, etc., lorsque je change la vue et met à jour l'URL avec des paramètres, mais je ne veux pas le symbole #.

Le tutoriel routeProvider est déclaré comme suit:

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

Puis-je modifier cela pour avoir les mêmes fonctionnalités sans le #?


13
hashtag nice one
BoJack Horseman


Pour moi, toutes les réponses ici sont fausses. Nous pouvons "réécrire" l'URL et supprimer le #, mais jamais accéder directement à la page Web sans #. Toute vraie solution ici ???
amdev

Voici la solution si vous utilisez Angular 1.6 .
Mistalis

Réponses:


251

Oui, vous devez configurer $locationProvideret définir html5Modesur 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
Parce que IE lt 10 ne prend pas en charge l'API d'historique html5 qui a été activée lors de la configuration html5Mode(true). Dans IE, vous devez utiliser #dans les itinéraires.
Maxim Grach

10
@powtac IE lt 10signifie Internet Explorer moins que la version 10
Maxim Grach

6
Pouvez-vous le définir de manière à utiliser # dans IE? Est - ce aussi simple que l' emballage juste $locationProvider.html5Mode(true);dans if !(IE lt 10)?
Andy Hayden

52
Cette solution résout donc la suppression du hashtag dans l'URL étant donné que l'URL a un hashtag, mais elle ne résout pas comment répondre aux demandes qui ne veulent pas que le hashtag soit inclus en premier lieu. Aka, il résout bla / # / téléphones -> bla / téléphones mais il ne gère pas directement bla / téléphones .
Luke

9
J'avais besoin de mettre <base href = "/" /> dans ma section index.html <head>.
nyxz

55

Assurez-vous de vérifier la prise en charge du navigateur pour l'API d'historique html5:

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

23
Cela pourrait être mieux adapté en tant que commentaire car il ne répond pas directement à la question.
brandonscript

31
Selon le guide du développeur , cette détection se fait automatiquement:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB

Fonctionné comme un charme, et j'apprécie la vérification des méthodes plutôt que la vérification de la version du navigateur - à l'épreuve du temps.
Shane

46

Pour supprimer la balise Hash pour une jolie URL et aussi pour que votre code fonctionne après la minification, vous devez structurer votre code comme dans l'exemple ci-dessous:

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
Pour le requireBase: false+1
whoan

2
Bonjour @digitlimit, Après avoir ajouté du $locationProvider.html5Modecode, mon code a $urlRouterProvider.otherwise('/home');cessé de fonctionner.
Jaikrat

18

J'écris une règle dans web.config après l'avoir $locationProvider.html5Mode(true)installée app.js.

Hope, aide quelqu'un.

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

Dans mon index.html, j'ai ajouté ceci à <head>

<base href="/">

N'oubliez pas d'installer le réécriteur d'URL pour iis sur le serveur.

De plus, si vous utilisez Web Api et IIS, cette URL de correspondance ne fonctionnera pas, car elle modifiera vos appels API. Donc, ajoutez une troisième entrée (troisième ligne de condition) et donnez un modèle qui exclura les appels dewww.yourdomain.com/api


1
Comment installer la réécriture d'URL pour IIS? J'héberge sur Azure.
Prabhu

11

Si vous êtes dans la pile .NET avec MVC avec AngularJS, voici ce que vous devez faire pour supprimer le '#' de l'URL:

  1. Configurez votre href de base dans votre page _Layout: <head> <base href="https://stackoverflow.com/"> </head>

  2. Ensuite, ajoutez ce qui suit dans la configuration de votre application angulaire: $locationProvider.html5Mode(true)

  3. Ci-dessus supprimera «#» de l'url mais l'actualisation de la page ne fonctionnera pas. Par exemple, si vous êtes dans la page «yoursite.com/about», la recréation de la page vous donnera un 404. Ceci est dû au fait que MVC ne connaît pas le routage angulaire et par modèle MVC il recherchera une page MVC pour «à propos» qui n'existe pas dans le chemin de routage MVC. La solution de contournement consiste à envoyer toutes les demandes de page MVC à une seule vue MVC et vous pouvez le faire en ajoutant un itinéraire qui les capture tous.

url:

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

Quel fichier dois-je ajouter les routes.MapRoute?
Vicheanak

1
RouteConfig.cs son sous le dossier App_Start
Maksood

5

Vous pouvez modifier le mode html5 mais cela ne fonctionne que pour les liens inclus dans les ancres html de votre page et à quoi ressemble l'url dans la barre d'adresse du navigateur. Tenter de demander une sous-page sans le hashtag (avec ou sans html5mode) de n'importe où en dehors de la page entraînera une erreur 404. Par exemple, la demande CURL suivante entraînera une erreur de page non trouvée, indépendamment de html5mode:

$ curl http://foo.bar/phones

bien que ce qui suit renverra la page racine / page d'accueil:

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

La raison en est que tout ce qui se trouve après le hashtag est supprimé avant que la demande n'arrive sur le serveur. Ainsi, une demande de http://foo.bar/#/portfolioarrive sur le serveur comme une demande de http://foo.bar. Le serveur répondra par une réponse 200 OK (vraisemblablement) http://foo.baret l'agent / client traitera le reste.

Donc, dans les cas où vous souhaitez partager une URL avec d'autres, vous n'avez pas d'autre choix que d'inclure le hashtag.


N'y a-t-il aucun moyen de contourner cela? C'est un gros problème.
user441521

5

Suivez 2 étapes -
1. Définissez d' abord $ locationProvider.html5Mode (true) dans le fichier de configuration de votre application.
Par exemple -
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2.Deuxièmement, définissez la <base> dans votre page principale.
Par exemple ->
<base href="https://stackoverflow.com/">

Le service $ location reprendra automatiquement la méthode de la partie de hachage pour les navigateurs qui ne prennent pas en charge l'API HTML5 History.


3

Ma solution est de créer .htaccess et d'utiliser le code #Sorian .. sans .htaccess, je n'ai pas réussi à supprimer #

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

Selon la documentation. Vous pouvez utiliser:

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

NB: Si votre navigateur ne supporte pas le HTML 5. Ne vous inquiétez pas: D il a recours au mode hashbang. Donc, vous n'avez pas besoin de vérifier if(window.history && window.history.pushState){ ... }manuellement

Par exemple: si vous cliquez sur: <a href="https://stackoverflow.com/other">Some URL</a>

Dans le navigateur HTML5 : angular redirigera automatiquement versexample.com/other

Dans le navigateur non HTML5 : angular redirigera automatiquement versexample.com/#!/other


1

Cette réponse suppose que vous utilisez nginx comme proxy inverse et que vous avez déjà défini $ locationProvider.html5mode sur true.

-> Pour les personnes qui pourraient encore avoir du mal avec tout ce qui est cool ci-dessus.

Certes, la solution @maxim grach fonctionne très bien, mais pour la solution pour répondre aux demandes qui ne veulent pas que le hashtag soit inclus en premier lieu, ce qui peut être fait est de vérifier si php envoie 404, puis de réécrire l'URL. Voici le code pour nginx,

Dans l'emplacement php, détectez l'erreur 404 php et redirigez-le vers un autre emplacement,

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

Réécrivez ensuite l'URL dans l'emplacement de redirection et proxy_passez les données, bien sûr, mettez l'URL de votre site Web à la place de l'URL de mon blog. (Demande: ne questionnez cela qu'après l'avoir essayé)

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

Et voyez la magie.

Et ça marche vraiment, du moins pour moi.


Où ajouter ça?
Volatil3

Où ajouter le code ci-dessus? Mettez-les dans le fichier de configuration principal de Nginx.
Satys

1

Commencez à partir de index.html supprimez tout #de <a href="#/aboutus">About Us</a>sorte qu'il doit ressembler à <a href="https://stackoverflow.com/aboutus">About Us</a>.Now dans la balise head de index.html écrivez <base href="https://stackoverflow.com/">juste après la dernière balise meta .

Maintenant, dans votre routage, injectez $locationProvideret écrivez $locatonProvider.html5Mode(true); quelque chose comme ça: -

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

Pour plus de détails, regardez cette vidéo https://www.youtube.com/watch?v=XsRugDQaGOo


La suppression de toutes les # URL a aidé, car je les testais sans supprimer les #urls.
optimistanoop

1

Je suppose que c'est vraiment tard pour ça. Mais l'ajout de la configuration ci-dessous aux importations app.module fait le travail:

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

0

Étape 1: injectez le service $ locationProvider dans le constructeur de la configuration de l'application

Étape 2: Ajoutez la ligne de code $ locationProvider.html5Mode (true) au constructeur de la configuration de l'application.

Étape 3: dans la page du conteneur (landing, master ou layout), ajoutez une balise html telle qu'à l' <base href="https://stackoverflow.com/">intérieur de la balise.

Étape 4: supprimez tous les '# "pour le routage de la configuration de toutes les balises d'ancrage. Par exemple, href =" # home "devient href =" home "; href =" # about "devient herf =" about "; href =" # contact "devient href =" contact "

 <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

Il suffit d' ajouter $locationProviderdans

.config(function ($routeProvider,$locationProvider)

puis ajouter $locationProvider.hashPrefix(''); après

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

C'est tout.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.