Le rechargement de la page donne une requête GET incorrecte avec le mode AngularJS HTML5

Je veux activer le mode HTML5 pour mon application. J’ai mis le code suivant pour la configuration, comme indiqué ici :

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

Comme vous pouvez le voir, j’ai utilisé le mode $locationProvider.html5mode et j’ai changé tous mes liens au ng-href pour exclure le /#/ .

Le problème

Pour le moment, je peux aller sur localhost:9000/ et voir la page d’index et accéder aux autres pages comme localhost:9000/about .

Cependant, le problème se produit lorsque j’actualise la page localhost:9000/about . J’obtiens la sortie suivante: Cannot GET /about

Si je regarde les appels réseau:

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

Alors que si je vais d’abord sur localhost:9000/ et puis cliquez sur un bouton qui navigue vers /about que j’obtiens:

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

Ce qui rend la page parfaitement.

Comment puis-je activer angular pour obtenir la bonne page lorsque je rafraîchit?

Des documents angulars

Du côté serveur
L’utilisation de ce mode nécessite la réécriture d’URL côté serveur. En gros, vous devez réécrire tous vos liens vers le point d’entrée de votre application (par exemple, index.html).

La raison en est que la première fois que vous visitez la page ( /about ), par exemple après une actualisation, le navigateur n’a aucun moyen de savoir qu’il ne s’agit pas d’une URL réelle. Cependant, si vous avez d’abord chargé la page racine et tout le code javascript, lorsque vous naviguez vers /about Angular, vous pouvez y accéder avant que le navigateur ne tente de bash le serveur et le gérer en conséquence.

Il y a peu de choses à configurer pour que votre lien dans le navigateur ressemble à http://yourdomain.com/path et que ce soit votre configuration angular + côté serveur

1) AngularJS

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

2) côté serveur, placez simplement .htaccess dans votre dossier racine et collez-le

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

Des choses plus intéressantes à lire sur le mode html5 dans angularjs et la configuration requirejse pour différents environnements https://github.com/angular-ui/ui-router/wiki/Fre souvent-Asked-Questions#how-to-configure-your-server -to-work-with-html5mode Aussi cette question pourrait vous aider à localiser / changer de mode html5 et de réécriture de mode hashbang / link

J’ai eu un problème similaire et je l’ai résolu en:

  • Utiliser dans la page d’index

  • En utilisant un middleware catch all route dans mon noeud / serveur Express comme suit (placez-le après le routeur):

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

Je pense que cela devrait vous permettre de démarrer.

Si vous utilisez un serveur Apache, vous voudrez peut-être modifier vos liens. Ce n’est pas difficile à faire. Quelques modifications dans les fichiers de configuration.

Tout ce qui suppose que html5mode est activé sur angularjs. À présent. notez que dans angular 1.2, déclarer une url de base n’est plus recommandé en fait.

Solution pour BrowserSync et Gulp.

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

Installez d’abord connect-history-api-fallback :

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

Puis ajoutez-le à votre fichier gulpfile.js:

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

Vous devez configurer votre serveur pour tout réécrire en index.html pour charger l’application:

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

J’ai écrit un middleware de connexion simple pour simuler la réécriture d’url sur les projets grunt. https://gist.github.com/muratcorlu/5803655

Vous pouvez utiliser comme ça:

 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 vous êtes dans la stack .NET avec MVC avec AngularJS, voici ce que vous devez faire pour supprimer le “#” de l’url:

  1. Configurez votre base href dans votre page _Layout:

  2. Ensuite, ajoutez les informations suivantes dans votre application angular: $locationProvider.html5Mode(true)

  3. Ci-dessus va supprimer “#” de l’URL mais l’actualisation de la page ne fonctionnera pas, par exemple si vous êtes dans “yoursite.com/about”, l’actualisation de la page vous donnera un 404. C’est parce que MVC ne connaît pas le routage angular cherchera une page MVC pour ‘about’ qui n’existe pas dans le chemin de routage MVC. La solution à ce problème consiste à envoyer toutes les requêtes de page MVC à une vue MVC unique et vous pouvez le faire en ajoutant une route qui intercepte toutes les URL.


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

Règle de réécriture d’URL IIS pour empêcher l’erreur 404 après l’actualisation de la page en mode html5

Pour un fonctionnement angular sous IIS sous Windows

             

NodeJS / ExpressJS Routes pour éviter l’erreur 404 après l’actualisation de la page en mode html5

Pour une course angular sous Node / 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; 

Plus d’infos sur: AngularJS – Activer l’actualisation de la page en mode HTML5 sans erreurs 404 dans NodeJS et IIS

Comme d’autres l’ont mentionné, vous devez réécrire les routes sur le serveur et définir .

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

J’utilise apache (xampp) sur mon environnement de développement et Apache sur la production, ajoutez:

 errorDocument 404 /index.html 

à la .htaccess résoudre pour moi ce problème.

J’ai résolu de

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

Je réponds à cette question de la plus grande question:

Lorsque j’ajoute $ locationProvider.html5Mode (true), mon site n’autorise pas le collage des URL. Comment configurer mon serveur pour qu’il fonctionne lorsque html5Mode est vrai?

Lorsque vous avez activé html5Mode, le caractère # ne sera plus utilisé dans vos URL. Le symbole # est utile car il ne nécessite aucune configuration côté serveur. Sans #, l’URL semble beaucoup plus agréable, mais nécessite également des réécritures côté serveur. Voici quelques exemples:

Pour Express Rewrites avec AngularJS, vous pouvez résoudre ce problème avec les mises à jour suivantes:

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

et

   

et

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

Pour Grunt et Browsersync, utilisez connect-modrewrite ici

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

Je crois que votre problème concerne le serveur. La documentation angular concernant le mode HTML5 (au lien dans votre question) indique:

Côté serveur L’utilisation de ce mode nécessite la réécriture d’URL côté serveur. En gros, vous devez réécrire tous vos liens vers le point d’entrée de votre application (par exemple, index.html).

Je crois que vous devrez configurer une réécriture d’URL de / à propos de /.

Nous avons eu une redirection de serveur dans Express:

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

et nous recevions toujours des problèmes de rafraîchissement de la page, même après avoir ajouté le .

Solution: assurez-vous d’utiliser des liens réels sur votre page pour naviguer. ne saisissez pas la route dans l’URL ou vous obtiendrez un rafraîchissement de la page. (erreur stupide, je sais)

😛

Finalement, j’ai trouvé un moyen de résoudre ce problème côté serveur car c’est plutôt un problème avec AngularJs. J’utilise Angularjs 1.5 et j’ai le même problème lors du rechargement de la page. Mais après avoir ajouté le code ci-dessous dans mon fichier server.js , c’est sauver ma journée mais ce n’est pas une solution correcte ou pas une bonne façon.

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

J’ai trouvé encore meilleur plugin Grunt, cela fonctionne si vous avez vos index.html et Gruntfile.js dans le même répertoire;

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

Après cela dans votre 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 ssortingct'; 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 }); } 

J’ai eu le même problème avec l’application angular Java + générée avec JHipster . Je l’ai résolu avec Filtre et liste de toutes les pages angulars des propriétés:

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

J’espère que ce sera utile pour quelqu’un.

Gulp + browserSync:

Installez connect-history-api-fallback via npm, puis configurez votre tâche serve gulp

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

Votre code côté serveur est JAVA, puis suivez les étapes ci-dessous.

étape 1: Téléchargez le fichier JAR urlrewritefilter Cliquez ici et enregistrez pour créer le chemin WEB-INF / lib

étape 2: Activer le mode HTML5 $ locationProvider.html5Mode (true);

étape 3: définir l’URL de base

étape 4: copier et coller dans votre WEB.XML

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

étape 5: créer un fichier dans WEN-INF / urlrewrite.xml

    / /index.html    /example /index.html   

J’ai cette solution simple que j’ai utilisée et ses travaux.

Dans App / Exceptions / Handler.php

Ajoutez ceci en haut:

 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 

Puis à l’intérieur de la méthode de rendu

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

J’ai résolu le problème en ajoutant ci-dessous l’extrait de code dans le fichier node.js.

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

Remarque: lorsque nous actualisons la page, celle-ci recherche l’API au lieu de la page Angular (à cause de la balise no # dans l’URL). En utilisant le code ci-dessus, je redirige vers l’URL avec #

Il suffit d’écrire une règle dans web.config

                

Dans l’index ajoutez ceci

  

cela fonctionne pour moi peut-être que vous avez oublié de définir Html5Mode app.config

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