it-swarm.com.de

Das Neuladen der Seite führt zu einer falschen GET-Anforderung im AngularJS-HTML5-Modus

Ich möchte den HTML5-Modus für meine App aktivieren. Ich habe den folgenden Code für die Konfiguration eingegeben, wie hier :

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

Wie Sie sehen, habe ich den $locationProvider.html5mode verwendet und alle meine Links am ng-href geändert, um den /#/ auszuschließen.

Das Problem

Im Moment kann ich zu localhost:9000/ gehen, die Indexseite sehen und zu den anderen Seiten wie localhost:9000/about navigieren. 

Das Problem tritt jedoch auf, wenn ich die Seite localhost:9000/about aktualisiere. Ich erhalte folgende Ausgabe: Cannot GET /about

Wenn ich mir die Netzwerkanrufe anschaue:

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

Wenn ich zuerst zu localhost:9000/ gehe und dann auf eine Schaltfläche klicke, die zu /about navigiert, bekomme ich:

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

Was macht die Seite perfekt. 

Wie kann ich angle aktivieren, um beim Aktualisieren die richtige Seite zu erhalten?

190

Aus den eckigen Dokumenten

Serverseite
In diesem Modus müssen Sie die URL auf der Serverseite neu schreiben. Grundsätzlich müssen Sie alle Links zum Einstiegspunkt Ihrer Anwendung (z. B. index.html) neu schreiben.

Der Grund dafür ist, dass beim ersten Besuch der Seite (/about) z. Nach einer Aktualisierung kann der Browser nicht feststellen, dass es sich nicht um eine echte URL handelt. Er wird also geladen und geladen. Wenn Sie jedoch zuerst die Stammseite und den gesamten Javascript-Code geladen haben, kann Angular bei der Navigation zu /about dort einsteigen, bevor der Browser versucht, den Server zu treffen und entsprechend zu behandeln

98
James Sharp

Es gibt einige Dinge, die eingerichtet werden müssen, so dass Ihr Link im Browser wie http://yourdomain.com/path aussieht, und dies sind Ihre winkligen Konfigurations- und Serverseiten

1) AngularJS

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

2) serverseitig, fügen Sie einfach .htaccess in Ihren Stammordner ein und fügen Sie diesen ein

RewriteEngine On 
Options FollowSymLinks

RewriteBase /

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

Weitere interessante Informationen über den HTML5-Modus in anglejs und die erforderliche Konfiguration je nach Umgebung https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your -server-to-work-with-html5mode Auch diese Frage kann Ihnen helfen $ location/Umschalten zwischen html5- und hashbang-Modus/Linkumschreiben

61
lokers

Ich hatte ein ähnliches Problem und löste es durch: 

  • Verwenden von <base href="/index.html"> auf der Indexseite

  • Verwenden Sie eine catch all route-Middleware in meinem Knoten/Express-Server wie folgt (hinter dem Router):

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

Ich denke, das sollte dich zum Laufen bringen.

Wenn Sie einen Apache-Server verwenden, möchten Sie möglicherweise die Links mod_rewrite. Es ist nicht schwer zu tun. Nur ein paar Änderungen in den Konfigurationsdateien.

All dies setzt voraus, dass Sie html5mode für anglejs ..__ aktiviert haben. Beachten Sie, dass in Winkel 1.2 das Deklarieren einer Basis-URL eigentlich nicht mehr empfohlen wird.

34
Taye

Lösung für BrowserSync und Gulp.

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

Zuerst connect-history-api-fallback installieren:

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

Dann fügen Sie es Ihrer gulpfile.js hinzu:

var historyApiFallback = require('connect-history-api-fallback');

gulp.task('serve', function() {
  browserSync.init({
    server: {
      baseDir: "app",
      middleware: [ historyApiFallback() ]
    }
  });
});
26
Oscar

Sie müssen Ihren Server so konfigurieren, dass er alles in index.html schreibt, um die App zu laden:

https://github.com/angular-ui/ui-router/wiki/Häufige-Gestellte-anfragen#wiki-how-to-configure-your-server-to-work-with-html5mode

13
grant

Ich habe eine einfache Connect-Middleware zum Simulieren von Url-Rewriting in grunzigen Projekten geschrieben. https://Gist.github.com/muratcorlu/5803655

Sie können so verwenden:

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)
            ];
          }
        }
      }
    }
  })
};
10
Murat Çorlu

Wenn Sie sich in einem .NET-Stack mit MVC mit AngularJS befinden, müssen Sie Folgendes tun, um das '#' von der URL zu entfernen: 

  1. Richten Sie Ihre Basis-Href auf Ihrer _Layout-Seite ein: <head> <base href="/"> </head>

  2. Fügen Sie dann in Ihrer Winkel-App-Konfiguration Folgendes hinzu: $locationProvider.html5Mode(true)

  3. Oben wird '#' von der URL entfernt, aber die Seitenaktualisierung funktioniert nicht, z. Wenn Sie sich in der Seite "yoursite.com/about" befinden, erhalten Sie eine Aktualisierung von 404. Dies liegt daran, dass MVC keine Kenntnisse über das Winkelrouting hat und anhand des MVC-Musters nach einer MVC-Seite für "about" sucht, die in MVC nicht vorhanden ist Routing-Pfad. Umgehung hierfür ist das Senden aller MVC-Seitenanfragen an eine einzige MVC-Ansicht. Sie können dies tun, indem Sie eine Route hinzufügen, die alle URL abfängt


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

IIS URL-Überschreibungsregel zum Verhindern des 404-Fehlers nach Seitenaktualisierung in html5mode

Für eckige Ausführung unter IIS unter Windows

<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" />
      </conditions>
      <action type="Rewrite" url="/" />
    </rule>
  </rules>
</rewrite>

NodeJS/ExpressJS Routen zur Vermeidung eines 404-Fehlers nach Seitenaktualisierung in html5mode

Für Winkelfahrt unter 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;

Weitere Informationen unter: AngularJS - HTML5-Modus-Seitenaktualisierung ohne Fehler in NodeJS und IIS aktivieren

8
Jason

Wie bereits erwähnt, müssen Sie die Routen auf dem Server neu schreiben und <base href="/"/> einstellen.

Für 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()
    ];
  }
  ...
})
....
5
Brett

Ich verwende Apache (xampp) in meiner Entwicklungsumgebung und Apache in der Produktion Add:

errorDocument 404 /index.html

zum .htaccess lösen für mich dieses Problem.

4
crlshn

Ich habe es gelöst 

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

Ich beantworte diese Frage aus der größeren Frage:

Wenn ich $ locationProvider.html5Mode (true) hinzufüge, lässt meine Site das Einfügen von URLs nicht zu. Wie konfiguriere ich meinen Server so, dass er funktioniert, wenn html5Mode wahr ist?

Wenn Sie html5Mode aktiviert haben, wird das Zeichen # nicht mehr in Ihren URLs verwendet. Das Symbol # ist hilfreich, da keine serverseitige Konfiguration erforderlich ist. Ohne # sieht die URL viel schöner aus, erfordert aber auch serverseitige Umschreibungen. Hier sind einige Beispiele:

Für Express-Rewrites mit AngularJS können Sie dies mit den folgenden Updates beheben:

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

und 

<!-- FOR ANGULAR ROUTING -->
<base href="/">

und

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

Verwenden Sie für Grunt und Browsersync connect-modrewrite hier

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

Ich glaube, Ihr Problem betrifft den Server. In der Winkeldokumentation zum HTML5-Modus (unter dem Link in Ihrer Frage) heißt es:

Serverseite Für diesen Modus muss die URL auf Serverseite neu geschrieben werden. Grundsätzlich müssen Sie alle Links zum Einstiegspunkt Ihrer Anwendung (z. B. index.html) neu schreiben.

Ich glaube, Sie müssen eine URL von/über/nach umschreiben.

2
lucuma

Wir hatten eine Serverumleitung in Express:

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

und wir bekamen immer noch Probleme mit der Seitenaktualisierung, auch nachdem wir den <base href="/" /> hinzugefügt hatten.

Lösung: Stellen Sie sicher, dass Sie auf Ihrer Seite echte Links verwenden, um zu navigieren. Geben Sie die Route nicht in die URL ein, oder Sie erhalten eine Aktualisierung der Seite. (dummer Fehler, ich weiß)

:-P

2
Cody

Endlich habe ich eine Möglichkeit, dieses Problem serverseitig zu lösen, da es sich eher um ein Problem mit AngularJs selbst handelt. Ich verwende 1.5 AngularJs und habe das gleiche Problem beim Neuladen der Seite. Aber nach dem Hinzufügen von unten Code in meinem server.js Datei es ist mein Tag retten , aber es ist keine richtige Lösung oder kein guter Weg.

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

Ich habe diese einfache Lösung und ihre Werke.

In App/Ausnahmen/Handler.php

Füge das oben hinzu:

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

Dann in der Render-Methode

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

Ich hatte das gleiche Problem mit Java + - Winkel - App, die mit JHipster generiert wurde. Ich löste es mit Filter und Liste aller Winkelseiten in Eigenschaften: 

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

Ich hoffe, es wird für jemanden hilfreich sein.

0
Igor Zboichik

Gulp + browserSync:

Installieren Sie connect-history-api-fallback über npm

var historyApiFallback = require('connect-history-api-fallback');

gulp.task('serve', function() {
  browserSync.init({
    proxy: {
            target: 'localhost:' + port,
            middleware: [ historyApiFallback() ]
        }
  });
});
0
Oscar Caicedo

Ich habe ein noch besseres Grunt-Plugin gefunden, das funktioniert, wenn Sie index.html und Gruntfile.js im selben Verzeichnis haben.

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

Danach in deiner 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)
          ];
        }
      },
    }
},
0
Michał Lach
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
        });
    }
0
keiwt

Ihr serverseitiger Code ist Java. Führen Sie dann die folgenden Schritte aus

schritt 1: Urlrewritefilter JAR herunterladen Hier klicken und speichern, um den Pfad WEB-INF/lib zu erstellen

schritt 2: Aktivieren Sie den HTML5-Modus. $ locationProvider.html5Mode (true);

schritt 3: Festlegen der Basis-URL <base href="/example.com/"/>

schritt 4: Kopieren und Einfügen in Ihre WEB.XML 

 <filter>
     <filter-name>UrlRewriteFilter</filter-name>
 <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

schritt 5: Erstellen Sie eine Datei in WEN-INF/urlrewrite.xml

 <urlrewrite default-match-type="wildcard">


    <rule>
            <from>/</from>
            <to>/index.html</to>
        </rule>

    <!--Write every state dependent on your project url-->
    <rule>
            <from>/example</from>
            <to>/index.html</to>
        </rule>
    </urlrewrite>
0
senthil raja

Ich habe das Problem durch Hinzufügen des folgenden Code-Snippets in der Datei node.js behoben.

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

Hinweis: Wenn Sie die Seite aktualisieren, sucht sie nach der API anstelle der Angular-Seite (Wegen des # -Tags in der URL.). Mit dem obigen Code leite ich zur URL mit # um

0
Ram Gollapalli