Volver a cargar la página proporciona una solicitud GET incorrecta con el modo HTML5 de AngularJS

Quiero habilitar el modo HTML5 para mi aplicación. He puesto el siguiente código para la configuración, como se muestra aquí :

return app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) { $locationProvider.html5Mode(true); $locationProvider.hashPrefix = '!'; $routeProvider.when('/', { templateUrl: '/views/index.html', controller: 'indexCtrl' }); $routeProvider.when('/about',{ templateUrl: '/views/about.html', controller: 'AboutCtrl' }); 

Como puede ver, utilicé el modo $locationProvider.html5mode y cambié todos mis enlaces en ng-href para excluir el /#/ .

El problema

Por el momento, puedo ir a localhost:9000/ y ver la página de índice y navegar a las otras páginas como localhost:9000/about .

Sin embargo, el problema se produce cuando actualizo el localhost:9000/about página localhost:9000/about . Obtengo el siguiente resultado: Cannot GET /about

Si miro las llamadas de red:

 Request URL:localhost:9000/about Request Method:GET 

Mientras que si primero voy a localhost:9000/ y luego hago clic en un botón que navega a /about I get:

 Request URL:http://localhost:9000/views/about.html 

Lo cual hace que la página sea perfecta.

¿Cómo puedo habilitar angular para obtener la página correcta cuando actualizo?

De los documentos angulares

Lado del servidor
El uso de este modo requiere la reescritura de URL en el lado del servidor, básicamente tiene que volver a escribir todos sus enlaces al punto de entrada de su aplicación (por ejemplo, index.html)

La razón de esto es que la primera vez que visita la página ( /about ), por ejemplo, después de una actualización, el navegador no tiene forma de saber que esta no es una URL real, por lo que continúa y la carga. Sin embargo, si primero ha cargado la página raíz y todo el código javascript, cuando navegue a /about Angular puede ingresar allí antes de que el navegador intente acceder al servidor y manejarlo en consecuencia.

Hay pocas cosas que configurar para que su enlace en el navegador se vea como http://yourdomain.com/path y estos sean su configuración angular + lado del servidor

1) AngularJS

 $routeProvider .when('/path', { templateUrl: 'path.html', }); $locationProvider .html5Mode(true); 

2) lado del servidor, simplemente ponga .htaccess dentro de su carpeta raíz y pegue esto

 RewriteEngine On Options FollowSymLinks RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /#/$1 [L] 

Más información interesante sobre el modo html5 en angularjs y la configuración requerida para cada entorno https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server -to-work-with-html5mode También esta pregunta podría ayudarlo $ ubicación / cambio entre html5 y hashbang mode / rewriting de enlace

Tuve un problema similar y lo resolví de la siguiente manera:

  • Usando en la página de índice

  • Usar un middleware de captura de todas las rutas en mi nodo / servidor Express de la siguiente manera (ponerlo después del enrutador):

 app.use(function(req, res) { res.sendfile(__dirname + '/Public/index.html'); }); 

Creo que eso debería ponerlo en funcionamiento.

Si usa un servidor apache, es posible que desee modificar sus enlaces a mod_rewrite. No es difícil de hacer Solo algunos cambios en los archivos de configuración.

Todo eso es asumiendo que tienes el modo html5 habilitado en angularjs. Ahora. tenga en cuenta que en angular 1.2, declarar una url base ya no se recomienda en realidad.

Solución para BrowserSync y Gulp.

De https://github.com/BrowserSync/browser-sync/issues/204#issuecomment-102623643

Primera instalación connect-history-api-fallback :

 npm --save-dev install connect-history-api-fallback 

Luego agrégalo a tu gulpfile.js:

 var historyApiFallback = require('connect-history-api-fallback'); gulp.task('serve', function() { browserSync.init({ server: { baseDir: "app", middleware: [ historyApiFallback() ] } }); }); 

Necesita configurar su servidor para reescribir todo en index.html para cargar la aplicación:

https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#wiki-how-to-configure-your-server-to-work-with-html5mode

Escribí un middleware de conexión simple para simular la reescritura de url en proyectos grunt. https://gist.github.com/muratcorlu/5803655

Puedes usar así:

 module.exports = function(grunt) { var urlRewrite = require('grunt-connect-rewrite'); // Project configuration. grunt.initConfig({ connect: { server: { options: { port: 9001, base: 'build', middleware: function(connect, options) { // Return array of whatever middlewares you want return [ // redirect all urls to index.html in build folder urlRewrite('build', 'index.html'), // Serve static files. connect.static(options.base), // Make empty directories browsable. connect.directory(options.base) ]; } } } } }) }; 

Si está en la stack de .NET 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 _Layout:

  2. A continuación, agregue los siguientes en su configuración de aplicación angular: $locationProvider.html5Mode(true)

  3. Arriba 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 conoce el enrutamiento angular y por el patrón MVC buscará una página MVC para ‘about’ que no existe en la ruta de enrutamiento MVC. La solución para esto es enviar toda la solicitud de página de MVC a una única vista de MVC y puede hacerlo agregando una ruta que capte todas las URL.


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

Regla de reescritura de URL de IIS para evitar el error 404 después de actualizar la página en html5mode

Para ejecutar angular bajo IIS en Windows

             

Rutas NodeJS / ExpressJS para evitar el error 404 después de la actualización de la página en el modo html5

Para un funcionamiento angular bajo Nodo / Express

 var express = require('express'); var path = require('path'); var router = express.Router(); // serve angular front end files from root path router.use('/', express.static('app', { redirect: false })); // rewrite virtual urls to angular app to enable refreshing of internal pages router.get('*', function (req, res, next) { res.sendFile(path.resolve('app/index.html')); }); module.exports = router; 

Más información en: AngularJS – Habilite la actualización de página en modo HTML5 sin errores 404 en NodeJS e IIS

Como han mencionado otros, necesita volver a escribir las rutas en el servidor y establecer .

Para gulp-connect :

npm install connect-pushstate

 var gulp = require('gulp'), connect = require('gulp-connect'), pushState = require('connect-pushstate/lib/pushstate').pushState; ... connect.server({ ... middleware: function (connect, options) { return [ pushState() ]; } ... }) .... 

Estoy usando apache (xampp) en mi entorno de desarrollo y apache en la producción, agregue:

 errorDocument 404 /index.html 

al .htaccess resolver este problema para mí.

Resolví

 test: { options: { port: 9000, base: [ '.tmp', 'test', '<%= yeoman.app %>' ], middleware: function (connect) { return [ modRewrite(['^[^\\.]*$ /index.html [L]']), connect.static('.tmp'), connect().use( '/bower_components', connect.static('./bower_components') ), connect.static('app') ]; } } }, 

Estoy respondiendo esta pregunta de la pregunta más grande:

Cuando agrego $ locationProvider.html5Mode (true), mi sitio no permitirá el pegado de URL. ¿Cómo configuro mi servidor para que funcione cuando html5Mode es verdadero?

Cuando haya habilitado html5Mode, el carácter # ya no se usará en sus URL. El símbolo # es útil porque no requiere configuración del lado del servidor. Sin #, la URL se ve mucho mejor, pero también requiere reescrituras del lado del servidor. Aquí hay unos ejemplos:

Para Express Rewrites con AngularJS, puede resolver esto con las siguientes actualizaciones:

 app.get('/*', function(req, res) { res.sendFile(path.join(__dirname + '/public/app/views/index.html')); }); 

y

   

y

 app.use('/',express.static(__dirname + '/public')); 

Para Grunt y Browsersync use connect-modrewrite aquí

 var modRewrite = require('connect-modrewrite'); browserSync: { dev: { bsFiles: { src: [ 'app/assets/css/*.css', 'app/*.js', 'app/controllers/*.js', '**/*.php', '*.html', 'app/jade/includes/*.jade', 'app/views/*.html', ], }, options: { watchTask: true, debugInfo: true, logConnections: true, server: { baseDir :'./', middleware: [ modRewrite(['!\.html|\.js|\.jpg|\.mp4|\.mp3|\.gif|\.svg\|.css|\.png$ /index.html [L]']) ] }, ghostMode: { scroll: true, links: true, forms: true } } } }, 

Creo que su problema es con respecto al servidor. La documentación angular con respecto al modo HTML5 (en el enlace de su pregunta) establece:

Lado del servidor El uso de este modo requiere la reescritura de URL en el lado del servidor, básicamente tiene que volver a escribir todos sus enlaces al punto de entrada de su aplicación (por ejemplo, index.html)

Creo que deberás configurar una reescritura de URL desde / hasta /.

Tuvimos una redirección de servidor en Express:

 app.get('*', function(req, res){ res.render('index'); }); 

y todavía estábamos recibiendo problemas de actualización de página, incluso después de que agregamos el .

Solución: asegúrese de estar utilizando enlaces reales en su página para navegar; no escriba la ruta en la URL o obtendrá una actualización de página. (error tonto, lo sé)

:-PAG

Finalmente encontré la manera de resolver este problema por el lado del servidor, ya que es más como un problema con AngularJs en sí. Estoy usando 1.5 Angularjs y tengo el mismo problema al volver a cargar la página. Pero después de agregar el código a continuación en mi archivo server.js , es salvar mi día pero no es una solución adecuada o no es una buena manera.

 app.use(function(req, res, next){ var d = res.status(404); if(d){ res.sendfile('index.html'); } }); 

He encontrado un plugin Grunt aún mejor, que funciona si tienes tu index.html y Gruntfile.js en el mismo directorio;

 https://npmjs.org/package/grunt-connect-pushstate 

Después de eso en tu Gruntfile:

  var pushState = require('grunt-connect-pushstate/lib/utils').pushState; connect: { server: { options: { port: 1337, base: '', logger: 'dev', hostname: '*', open: true, middleware: function (connect, options) { return [ // Rewrite requests to root so they may be handled by router pushState(), // Serve static files connect.static(options.base) ]; } }, } }, 
 I solved same problem using modRewrite. AngularJS is reload page when after # changes. But HTML5 mode remove # and invalid the reload. So we should reload manually. # install connect-modrewrite $ sudo npm install connect-modrewrite --save # gulp/build.js 'use strict'; var gulp = require('gulp'); var paths = gulp.paths; var util = require('util'); var browserSync = require('browser-sync'); var modRewrite = require('connect-modrewrite'); function browserSyncInit(baseDir, files, browser) { browser = browser === undefined ? 'default' : browser; var routes = null; if(baseDir === paths.src || (util.isArray(baseDir) && baseDir.indexOf(paths.src) !== -1)) { routes = { '/bower_components': 'bower_components' }; } browserSync.instance = browserSync.init(files, { startPath: '/', server: { baseDir: baseDir, middleware: [ modRewrite([ '!\\.\\w+$ /index.html [L]' ]) ], routes: routes }, browser: browser }); } 

Tuve el mismo problema con la aplicación java + angular generada con JHipster . Lo resolví con Filtro y lista de todas las páginas angulares en propiedades:

application.yml:

 angular-pages: - login - settings ... 

AngularPageReloadFilter.java

 public class AngularPageReloadFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.getRequestDispatcher("index.html").forward(request, response); } } 

WebConfigurer.java

 private void initAngularNonRootRedirectFilter(ServletContext servletContext, EnumSet disps) { log.debug("Registering angular page reload Filter"); FilterRegistration.Dynamic angularRedirectFilter = servletContext.addFilter("angularPageReloadFilter", new AngularPageReloadFilter()); int index = 0; while (env.getProperty("angular-pages[" + index + "]") != null) { angularRedirectFilter.addMappingForUrlPatterns(disps, true, "/" + env.getProperty("angular-pages[" + index + "]")); index++; } angularRedirectFilter.setAsyncSupported(true); } 

Espero, será útil para alguien.

Gulp + browserSync:

Instale connect-history-api-fallback a través de npm, luego configure su tarea serve gulp

 var historyApiFallback = require('connect-history-api-fallback'); gulp.task('serve', function() { browserSync.init({ proxy: { target: 'localhost:' + port, middleware: [ historyApiFallback() ] } }); }); 

El código del lado del servidor es JAVA y luego sigue estos pasos a continuación

paso 1: descarga urlrewritefilter JAR Haz clic aquí y guarda para comstackr la ruta WEB-INF / lib

paso 2: habilitar el modo HTML5 $ locationProvider.html5Mode (true);

paso 3: establecer URL base

paso 4: copiar y pegar en tu WEB.XML

   UrlRewriteFilter org.tuckey.web.filters.urlrewrite.UrlRewriteFilter   UrlRewriteFilter /* REQUEST FORWARD  

paso 5: crear archivo en WEN-INF / urlrewrite.xml

    / /index.html    /example /index.html   

Tengo esta solución simple que he estado usando y su trabajo.

En App / Exceptions / Handler.php

Agregar esto en la parte superior:

 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 

Luego dentro del método de renderizado

 public function render($request, Exception $exception) { ....... if ($exception instanceof NotFoundHttpException){ $segment = $request->segments(); //eg. http://site.dev/member/profile //module => member // view => member.index //where member.index is the root of your angular app could be anything :) if(head($segment) != 'api' && $module = $segment[0]){ return response(view("$module.index"), 404); } return response()->fail('not_found', $exception->getCode()); } ....... return parent::render($request, $exception); } 

Resolví el problema agregando el siguiente fragmento de código en el archivo node.js.

 app.get("/*", function (request, response) { console.log('Unknown API called'); response.redirect('/#' + request.url); }); 

Nota: cuando actualizamos la página, buscará la API en lugar de la página Angular (Debido a que no hay una etiqueta # en la URL). Usando el código anterior, estoy redirigiendo a la url con #

Simplemente escriba una regla en web.config

                

En el índice agrega esto

  

funciona para mí tal vez haya olvidado configurar Html5Mode app.config

 app.config(function ($stateProvider, $urlRouterProvider, $locationProvider){ $locationProvider.html5Mode({ enabled: true, requireBase: true }); $locationProvider.hashPrefix('!'); } 
    Intereting Posts