Eliminar el identificador de fragmento de las URL de AngularJS (símbolo #)

257

¿Es posible eliminar el símbolo # de las URL de angular.js?

Todavía quiero poder usar el botón de retroceso del navegador, etc., cuando cambio la vista y actualice la URL con parámetros, pero no quiero el símbolo #.

El tutorial routeProvider se declara de la siguiente manera:

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

¿Puedo editar esto para tener la misma funcionalidad sin el #?

Tim Webster
fuente
13
hashtag nice one
BoJack Horseman
Para mí, todas las respuestas aquí son incorrectas. Podemos "reescribir" la url y eliminar el #, pero nunca acceder directamente a la página web sin #. ¿Alguna solución real aquí?
amdev
Aquí está la solución si está utilizando Angular 1.6 .
Mistalis

Respuestas:

251

Sí, debe configurar $locationProvidery configurar 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);

  }]);
Maxim Grach
fuente
10
Porque IE lt 10 no es compatible con la API de historial html5 que se habilitaron mediante la configuración html5Mode(true). En IE tienes que usar #en rutas.
Maxim Grach
10
@powtac IE lt 10significa Internet Explorer menos que la versión 10
Maxim Grach
66
¿Puedes configurarlo para que esto recurra al uso de # en IE? Es tan simple como envolver $locationProvider.html5Mode(true);en if !(IE lt 10)?
Andy Hayden
52
Entonces, esta solución resuelve la eliminación del hashtag en la url dado que la url tiene un hashtag, sin embargo, no resuelve cómo responder a las solicitudes que no quieren que el hashtag se incluya en primer lugar. También, resuelve blah / # / phones -> blah / phones pero no maneja blah / phones directamente.
Lucas
9
Necesitaba poner <base href = "/" /> en mi sección index.html <head>.
nyxz
55

Asegúrese de consultar el soporte del navegador para la API de historial html5:

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }
SSaidi
fuente
23
Esto podría ser más adecuado como comentario, ya que no responde directamente a la pregunta.
brandonscript
31
Según la guía del desarrollador , esta detección se realiza automáticamente:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB
Funcionó de maravilla, y aprecio la verificación de métodos en lugar de la verificación de la versión del navegador: prueba futura
Shane
46

Para eliminar la etiqueta Hash para una URL bonita y también para que su código funcione después de la minificación , debe estructurar su código como en el siguiente ejemplo:

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
fuente
15
Para el requireBase: false+1
whoan
2
Hola @digitlimit, después de agregar $locationProvider.html5Modecódigo, mi código $urlRouterProvider.otherwise('/home');dejó de funcionar.
Jaikrat
18

Escribo una regla en web.config después de que $locationProvider.html5Mode(true)se establece app.js.

Esperanza, ayuda a alguien.

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

En mi index.html agregué esto a <head>

<base href="/">

No olvide instalar url rewriter para iis en el servidor.

Además, si usa Web Api e IIS, esta url de coincidencia no funcionará, ya que cambiará sus llamadas de API. Por lo tanto, agregue la tercera entrada (tercera línea de condición) y proporcione un patrón que excluya las llamadas dewww.yourdomain.com/api

Yagiz Ozturk
fuente
1
¿Cómo instalar url rewriter para IIS? Estoy alojando en Azure.
Prabhu
11

Si está en .NET stack con MVC con AngularJS, esto es lo que debe hacer para eliminar el '#' de la URL:

  1. Configure su href base en su página _Diseño: <head> <base href="https://stackoverflow.com/"> </head>

  2. Luego, agregue lo siguiente en la configuración angular de su aplicación: $locationProvider.html5Mode(true)

  3. Lo anterior eliminará '#' de la URL, pero la actualización de la página no funcionará, por ejemplo, si está en "yoursite.com/about", la actualización de la página le dará un 404. Esto se debe a que MVC no sabe sobre el enrutamiento angular y por el patrón MVC buscará una página MVC para "acerca de" que no existe en la ruta de enrutamiento MVC. La solución para esto es enviar todas las solicitudes de página MVC a una sola vista MVC y puede hacerlo agregando una ruta que capture todo

url:

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);
Maksood
fuente
¿Qué archivo debo agregar al route.MapRoute?
Vicheanak
1
RouteConfig.cs está en la carpeta App_Start
Maksood
5

Puede ajustar el modo html5 pero eso solo es funcional para los enlaces incluidos en los anclajes html de su página y cómo se ve la url en la barra de direcciones del navegador. Intentar solicitar una subpágina sin el hashtag (con o sin html5mode) desde cualquier lugar fuera de la página dará como resultado un error 404. Por ejemplo, la siguiente solicitud CURL dará como resultado un error de página no encontrada, independientemente de html5mode:

$ curl http://foo.bar/phones

aunque lo siguiente devolverá la raíz / página de inicio:

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

La razón de esto es que cualquier cosa después de quitar el hashtag antes de que la solicitud llegue al servidor. Entonces, una solicitud de http://foo.bar/#/portfoliollega al servidor como una solicitud de http://foo.bar. El servidor responderá con una respuesta de 200 OK (presumiblemente) http://foo.bary el agente / cliente procesará el resto.

Entonces, en los casos en que desea compartir una URL con otros, no tiene más opción que incluir el hashtag.

Chris
fuente
¿No hay forma de evitar esto? Este es un problema bastante grande.
user441521
5

Siga 2 pasos:
1. Primero configure $ locationProvider.html5Mode (verdadero) en el archivo de configuración de su aplicación.
Por ej.
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2. Segundo configure la <base> dentro de su página principal.
Por ej. ->
<base href="https://stackoverflow.com/">

El servicio $ location recurrirá automáticamente al método de parte hash para los navegadores que no admiten la API de historial HTML5.

Anshul Bisht
fuente
3

Mi solución es crear .htaccess y usar el código #Sorian ... sin .htaccess no pude eliminar #

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

De acuerdo con la documentación. Puedes usar:

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

NB: si su navegador no es compatible con HTML 5. No se preocupe: D tiene respaldo al modo hashbang. Por lo tanto, no necesita consultar if(window.history && window.history.pushState){ ... }manualmente

Por ejemplo: si hace clic en: <a href="https://stackoverflow.com/other">Some URL</a>

En el navegador HTML5 : angular redirigirá automáticamente aexample.com/other

En el navegador no HTML5 : angular redirigirá automáticamente aexample.com/#!/other

Efriandika Pratama
fuente
1

Esta respuesta supone que está utilizando nginx como proxy inverso y que ya configuró $ locationProvider.html5mode en verdadero.

-> Para las personas que aún podrían estar luchando con todas las cosas interesantes anteriores.

Seguramente, la solución @maxim grach funciona bien, pero para la solución de cómo responder a las solicitudes que no quieren que se incluya el hashtag en primer lugar, lo que se puede hacer es verificar si php está enviando 404 y luego reescribir la url. El siguiente es el código para nginx,

En la ubicación php, detecta el error 404 php y redirige a otra ubicación,

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

Luego, reescriba la URL en la ubicación de redireccionamiento y proxy_pass los datos, por supuesto, coloque la URL de su sitio web en el lugar de la URL de mi blog. (Solicitud: cuestione esto solo después de haberlo intentado)

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

Y mira la magia.

Y definitivamente funciona, al menos para mí.

Sábados
fuente
¿Dónde agregar esto?
Volatil3
¿Dónde agregar el código anterior? Póngalos en el archivo de configuración principal de Nginx.
Sábados
1

Comience desde index.html, elimine todo, #por <a href="#/aboutus">About Us</a>lo que debe verse como <a href="https://stackoverflow.com/aboutus">About Us</a>.Ahora en la etiqueta principal de index.html, escriba <base href="https://stackoverflow.com/">justo después de la última metaetiqueta .

Ahora en su enrutamiento js inyecte $locationProvidery escriba $locatonProvider.html5Mode(true); algo como esto: -

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

Para obtener más detalles, vea este video https://www.youtube.com/watch?v=XsRugDQaGOo

Aniket Jha
fuente
Eliminar todo # Url ayudó porque lo estaba probando sin eliminar #urls.
optimistanoop
1

Supongo que esto es realmente tarde para esto. Pero agregar la configuración a continuación a las importaciones de app.module hace el trabajo:

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

Paso 1: inyecta el servicio $ locationProvider en el constructor de la configuración de la aplicación

Paso 2: Agregue la línea de código $ locationProvider.html5Mode (true) al constructor de la configuración de la aplicación.

Paso 3: en la página del contenedor (aterrizaje, master o diseño), agregue la etiqueta html como <base href="https://stackoverflow.com/">dentro de la etiqueta.

Paso 4: elimine todos los '# "para la configuración de enrutamiento de todas las etiquetas de anclaje. Por ejemplo, href =" # home "se convierte en href =" home "; href =" # about "se convierte en herf =" about "; href =" # contact "se convierte en href =" contacto "

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

Sólo tiene que añadir $locationProviderEn

.config(function ($routeProvider,$locationProvider)

y luego agregue $locationProvider.hashPrefix(''); después

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

Eso es.

Narendra Solanki
fuente