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

Tim Webster
la source
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);

  }]);
Maxim Grach
la source
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);
  }
SSaidi
la source
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
          });
        }
    }]);
Emeka Mbah
la source
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

Yagiz Ozturk
la source
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"
    }
);
Maksood
la source
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.

chris
la source
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.

Anshul Bisht
la source
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]
Thomas Knápek
la source
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

Efriandika Pratama
la source
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.

Satys
la source
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

Aniket Jha
la source
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 })
Sagar Bhat
la source
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>
Thomas.Benz
la source
-1

Il suffit d' ajouter $locationProviderdans

.config(function ($routeProvider,$locationProvider)

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

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

C'est tout.

Narendra Solanki
la source