Il ricaricamento della pagina fornisce una richiesta GET errata con la modalità HTML5 di AngularJS

Voglio abilitare la modalità HTML5 per la mia app. Ho messo il seguente codice per la configurazione, come mostrato qui :

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

Come puoi vedere, ho usato $locationProvider.html5mode e ho modificato tutti i miei link su ng-href per escludere /#/ .

Il problema

Al momento, posso andare a localhost:9000/ e vedere la pagina indice e navigare verso le altre pagine come localhost:9000/about .

Tuttavia, il problema si verifica quando aggiorno l’ localhost:9000/about pagina. Ottengo il seguente risultato: Cannot GET /about

Se guardo le chiamate di rete:

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

    Mentre se prima vado a localhost:9000/ e poi clic su un pulsante che si sposta su /about ottengo:

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

    Che rende perfettamente la pagina.

    Come posso abilitare l’angular per ottenere la pagina corretta quando aggiorno?

    Dai documenti angolari

    Lato server
    L’utilizzo di questa modalità richiede la riscrittura degli URL sul lato server, in pratica devi riscrivere tutti i tuoi link al punto di ingresso della tua applicazione (ad es. Index.html)

    La ragione di ciò è che quando visiti per la prima volta la pagina ( /about ), ad esempio dopo un aggiornamento, il browser non ha modo di sapere che questo non è un vero URL, quindi va avanti e lo carica. Tuttavia, se prima hai caricato la pagina principale e tutto il codice javascript, quando accedi a /about Angular puoi entrare prima che il browser tenti di colpire il server e gestirlo di conseguenza

    Ci sono poche cose da configurare in modo che il tuo link nel browser assomigli a http://yourdomain.com/path e queste sono la tua configurazione angular + lato server

    1) AngularJS

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

    2) lato server, basta inserire .htaccess nella cartella principale e incollarlo

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

    Cose più interessanti da leggere sulla modalità html5 in angularjs e la configurazione richiesta per ambiente diverso https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server -to-work-with-html5mode Anche questa domanda potrebbe aiutarti $ posizione / passaggio tra html5 e hashbang mode / link rewriting

    Ho avuto un problema simile e l’ho risolto con:

    • Usando nella pagina indice

    • Utilizzando un middleware catch all route nel mio nodo / server Express come indicato di seguito (posizionarlo dopo il router):

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

    Penso che dovrebbe farti funzionare.

    Se usi un server Apache, potresti mod_rewrite i tuoi link. Non è difficile da fare. Solo alcune modifiche nei file di configurazione.

    Tutto ciò presuppone che html5mode sia abilitato su angularjs. Adesso. si noti che in angular 1.2, dichiarare che un url di base non è più raccomandato in realtà.

    Soluzione per BrowserSync e Gulp.

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

    Innanzitutto installa connect-history-api-fallback :

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

    Quindi aggiungilo al tuo gulpfile.js:

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

    Devi configurare il tuo server per riscrivere tutto su index.html per caricare l’app:

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

    Ho scritto un semplice middleware di connessione per simulare la riscrittura dell’URL sui progetti di grunt. https://gist.github.com/muratcorlu/5803655

    Puoi usare così:

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

    Se sei nello stack .NET con MVC con AngularJS, questo è quello che devi fare per rimuovere il ‘#’ dall’URL:

    1. Imposta il tuo href di base nella tua pagina _Layout:

    2. Quindi, aggiungi la seguente configurazione di app angular: $locationProvider.html5Mode(true)

    3. Sopra rimuoverà “#” dall’url, ma l’aggiornamento della pagina non funzionerà, ad es. Se ci si trova in “yoursite.com/about” l’aggiornamento della pagina ti darà un 404. Questo perché MVC non conosce il routing angular e MVC lo modella cercherà una pagina MVC per “about” che non esiste nel percorso di routing MVC. Per ovviare a questo problema, è necessario inviare tutte le richieste di pagina MVC a una singola vista MVC e puoi farlo aggiungendo una route che raccoglie tutti gli URL


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

    Regola di riscrittura dell’URL di IIS per impedire l’errore 404 dopo l’aggiornamento della pagina in html5mode

    Per il funzionamento angular sotto IIS su Windows

                 

    NodeJS / ExpressJS Percorsi per prevenire l’errore 404 dopo l’aggiornamento della pagina in html5mode

    Per funzionamento angular sotto 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; 

    Maggiori informazioni su: AngularJS – Abilita aggiornamento della pagina in modalità HTML5 senza errori 404 in NodeJS e IIS

    Come altri hanno già detto, è necessario riscrivere le rotte sul server e impostare .

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

    Sto usando apache (xampp) sul mio ambiente di sviluppo e apache sulla produzione, aggiungo:

     errorDocument 404 /index.html 

    al .htaccess risolva per me questo problema.

    Ho risolto

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

    Sto rispondendo a questa domanda dalla domanda più ampia:

    Quando aggiungo $ locationProvider.html5Mode (true), il mio sito non consentirà di incollare url. Come posso configurare il mio server affinché funzioni quando html5Mode è true?

    Quando hai triggersto html5Mode, il carattere # non verrà più utilizzato negli URL. Il simbolo # è utile perché non richiede alcuna configurazione lato server. Senza #, l’url sembra molto più bello, ma richiede anche riscritture sul lato server. Ecco alcuni esempi:

    Per Express Rewrites con AngularJS, puoi risolvere questo problema con i seguenti aggiornamenti:

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

    e

       

    e

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

    Per Grunt e Browsersync usa connect-modrewrite qui

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

    Credo che il tuo problema riguardi il server. La documentazione angular relativa alla modalità HTML5 (al link nella tua domanda) afferma:

    Lato server L’utilizzo di questa modalità richiede la riscrittura degli URL sul lato server, in pratica è necessario riscrivere tutti i collegamenti al punto di ingresso dell’applicazione (ad es. Index.html)

    Credo che dovrai configurare una riscrittura di URL da / about a /.

    Abbiamo avuto un reindirizzamento del server in Express:

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

    e stavamo ancora riscontrando problemi di aggiornamento della pagina, anche dopo aver aggiunto .

    Soluzione: assicurati di utilizzare collegamenti reali nella tua pagina per navigare; non digitare il percorso nell’URL o riceverai un aggiornamento della pagina. (errore stupido, lo so)

    😛

    Finalmente ho trovato un modo per risolvere questo problema dal lato server in quanto è più come un problema con AngularJs stesso Sto usando 1.5 Angularjs e ho avuto lo stesso problema per ricaricare la pagina. Ma dopo aver aggiunto sotto il codice nel mio file server.js è ansible salvare la mia giornata ma non è una soluzione adeguata o non è un buon modo.

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

    Ho trovato un plugin Grunt ancora migliore, che funziona se hai il tuo index.html e Gruntfile.js nella stessa directory;

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

    Dopo quello nel tuo 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 }); } 

    Ho avuto lo stesso problema con l’app java + angular generata con JHipster . L’ho risolto con Filtro ed elenco di tutte le pagine angolari nelle proprietà:

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

    Spero, sarà utile per qualcuno.

    Gulp + browserSync:

    Installa connect-history-api-fallback via npm, successivamente configura il tuo compito gulp

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

    Il tuo side code del server è JAVA, quindi segui questa procedura

    passo 1: Scarica urlrewritefilter JAR Clicca qui e salva per build il percorso WEB-INF / lib

    passo 2: Abilita la modalità HTML5 $ locationProvider.html5Mode (true);

    passo 3: imposta l’URL di base

    fase 4: copia e incolla sul tuo WEB.XML

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

    passo 5: creare il file in WEN-INF / urlrewrite.xml

        / /index.html    /example /index.html   

    Ho questa semplice soluzione che ho usato e le sue opere.

    In App / Exceptions / Handler.php

    Aggiungi questo in cima:

     use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 

    Quindi all’interno del metodo di rendering

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

    Ho risolto il problema aggiungendo lo snippet di codice seguente nel file node.js.

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

    Nota: quando aggiorniamo la pagina, cercherà l’API al posto della pagina Angolare (a causa di nessun tag # nell’URL). Utilizzando il codice sopra, sto reindirizzando l’url con #

    Basta scrivere una regola in web.config

                    

    Nell’indice aggiungi questo

      

    funziona per me forse hai dimenticato di impostare Html5Mode app.config

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