2015-04-29 3 views
13

Ich benutze Angular UI Router in meiner eckigen App und ich habe HTML5-Modus aktiviert, um die # Form der URL mit $ LocationProvider in der Konfig zu entfernen.Seite neu laden bei Verwendung von Angular Ui Router mit Html5-Modus aktiviert

var app = angular.module('openIDC', ['ui.router']); 
app.config(function($urlRouterProvider, $stateProvider, $locationProvider) { 

    $locationProvider.html5Mode(true); 

    $urlRouterProvider.otherwise('/'); 

    $stateProvider 
    .state('home', { 
     url: '/', 
     templateUrl: 'views/home.html', 
     controller: 'HomeController' 
    }) 
    .state('login', { 
     url: '/login', 
     templateUrl: 'views/login.html', 
     controller: 'LoginController' 
    }) 
}); 

Ich habe setzen auch den <base href="/" />-Tag in der index.html auch Datei. Das Routing funktioniert gut und ich kann zu den Seiten navigieren und die # wird entfernt, aber wenn ich die Seite mit dem Reload-Button im Browser aktualisieren, gibt es eine 404-Fehlerreaktion.

enter image description here

Warum ist das passiert und wie kann ich es beheben und haben HTML5-Modus, es wäre die richtige URLs

Antwort

12

Kasun, der Grund, dass dies auftritt, weil Sie die Seite von einem Ihrer Unter Routen zu aktualisieren versuchen, (hat nichts mit ui zu tun -router).

Grundsätzlich, wenn Sie www.yourdomain.com/ anfordern, haben Sie wahrscheinlich Ihre Server-Setup index.html, die Ihre eckige App Bootstraps zurückgibt. Sobald die App geladen ist, nehmen weitere URL-Änderungen html5Mode in Betracht und aktualisieren Sie Ihre Seite über UI-Router.

Wenn Sie Ihre Seite neu laden, ist die eckige App nicht mehr gültig, da sie noch nicht geladen wurde. Wenn Sie also eine Unterroute laden möchten (z. B. www.yourdomain.com/someotherpage), weiß Ihr Server nicht, wie er damit umgehen soll /someotherpage und wahrscheinlich gibt 404 oder einen anderen Fehler zurück.

Was Sie tun müssen, ist Ihren Server zu konfigurieren, um Ihre eckige App für alle Routen zurückzugeben. Ich verwende in erster Linie Knoten/ausdrücken, so dass ich so etwas wie:

app.get('*', function(req, res, next) { 
    // call all routes and return the index.html file here 
} 

Hinweis: ich in der Regel so etwas wie dies als endgültiger Fang verwende alles aber ich auch andere Routen darüber für Dinge wie statische Dateien anfordert, Webcrawler und andere spezifische Routen, die behandelt werden müssen.

+0

Das ist im Grunde die Lösung. Eine Sache möchte ich hinzufügen: Wenn Ihr Backend auch dynamische Daten, z. Wenn Sie eine API verwenden, möchten Sie die API von dieser Umleitung isolieren. Daher müssen Sie diese Regel nur hinzufügen, wenn eine Datei, die der Anforderung entspricht, nicht existiert und auch keine andere API-Route übereinstimmt. –

+0

Guter Punkt. Meine Antwort wurde aktualisiert. Wie für APIs, bevorzuge ich es, sie von einer separaten URL/Domäne auszuführen. –

+0

Es gibt ein gutes Beispiel für NodeJS, die hier ein SPA anbieten: http://stackoverflow.com/questions/20396900/angularjs-routing-in-expressjs – mbokil

8

Sie müssen Setup-URL Rewrite auf Server-Seite

für Apache aktiviert so etwas wie:

RewriteEngine On 
RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule . index.html 

in .htaccess Datei (sicher sein, dass mod_rewrite apache-Modul ist enabled)

und Config, wie dies für nginx:

location/{ 
    .... 
    try_files $uri $uri/ /index.html =404; 
} 
+0

Wie machen Sie dasselbe in IIS? –

+1

Nicht sicher, noch nie in IIS getan. Aber diese Antwort sieht richtig aus: http://stackoverflow.com/questions/12614072/how-do-i-configure-iis-for-url-rewriting-an-angularjs-application-in-html5-mode#26152011 –

3

ersten make .htaccess-Datei kopieren Sie dann hinter diesem Code

<ifModule mod_rewrite.c> 
    RewriteEngine on 

    # Don't rewrite files or directories 
    RewriteCond %{REQUEST_FILENAME} -f [OR] 
    RewriteCond %{REQUEST_FILENAME} -d 
    RewriteRule^- [L] 


    RewriteRule^your root folder/index.html [L] 
     </ifModule> 


<base url="/"></base> in index.html file 
2

Cant in Einzelheiten erklären, warum dies geschieht, aber ich kann Ihnen einen Weg beschreiben, ich dieses Problem gelöst werden. Also habe ich UrlRewriterFilter für mein SpringMvc-Backend verwendet. Eckige allgemeine Modulkonfiguration:

var app = angular.module('ilonaChatGeneralModule', 
    [ 
     'ui.router' 
    ]); 

app.config(function($locationProvider){ 
    $locationProvider.html5Mode(true); 
}); 

app.config(function($stateProvider, $urlRouterProvider) { 

    $urlRouterProvider.otherwise('/'); 

    var home = ['/', { 
     url: '/', 
     templateUrl: 'views/userlist.html' 
    }]; 

    var login = ['login', { 
     url: '/login', 
     templateUrl: 'views/login.html' 
    }]; 

    var privateRoom = ['privateroom', { 
     url: '/privateroom', 
     templateUrl: 'views/privateroom.html' 
    }]; 

    $stateProvider 
     .state(home) 
     .state(login) 
     .state(privateRoom) 
     ; 
}); 

Meine Homepage, Index.html:

<html ng-app="ilonaChatGeneralModule" ng-controller="ilonaChatGeneralCtrl"> 
<head> 
    <base href="/"> 
    ... 

</head> 
<body> 
<div> 
    <div ui-view=""></div> 
</div> 
</body> 
</html> 

Dies ist Frontend. Ich UrlRewriteFilter für Backend verwendet, können Sie es mit folgenden Maven Abhängigkeit erhalten:

package com.sbk.config; 

    import org.springframework.context.ApplicationContext; 
    import org.springframework.web.context.ContextLoaderListener; 
    import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; 
    import org.springframework.web.filter.CharacterEncodingFilter; 
    import org.springframework.web.servlet.DispatcherServlet; 
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 
    import org.tuckey.web.filters.urlrewrite.UrlRewriteFilter; 

    import javax.servlet.*; 
    import java.nio.charset.StandardCharsets; 
    import java.util.EnumSet; 

    public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 
     private static final String URL_REWRITE_FILTER_NAME = "urlRewrite"; 
     private static final String URL_REWRITE_FILTER_MAPPING = "/*"; 

... 
     @Override 
     public void onStartup(ServletContext servletContext) throws ServletException { 
      super.onStartup(servletContext); 

      FilterRegistration.Dynamic urlReWrite = servletContext.addFilter(URL_REWRITE_FILTER_NAME, new UrlRewriteFilter()); 
      EnumSet<DispatcherType> urlReWriteDispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD); 
      urlReWrite.addMappingForUrlPatterns(urlReWriteDispatcherTypes, true, URL_REWRITE_FILTER_MAPPING); 
     } 
    } 

Dieser Filter erfordert urlrewrite.xml unter file:

<dependency> 
     <groupId>org.tuckey</groupId> 
     <artifactId>urlrewritefilter</artifactId> 
     <version>4.0.3</version> 
    </dependency> 

ich es meinem SpringMVC WebAppInitializer in der nächsten Weise hinzugefügt haben Ihr WEB-INF-Verzeichnis (scheint in konfigurierbar aber Standard-Ort - hier). Inhalt dieser Datei:

<!DOCTYPE urlrewrite 
     PUBLIC "-//tuckey.org//DTD UrlRewrite 2.6//EN" 
     "http://www.tuckey.org/res/dtds/urlrewrite2.6.dtd"> 

<urlrewrite> 

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

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

</urlrewrite> 

ich nicht Handbücher sorgfältig gelesen habe, aber ich vermute, dass Idee ist, wenn Sie ur-Browser mit http://yourhost:xxxx/privateroom ur App aktualisieren versuchen physicaly bestehende Ansicht http://yourhost:xxxx/privateroom zu finden. Aber es ist abwesend. Und wenn Sie es auf Ihre Basisseite umlenken, würde die korrekte Verbindung zur physischen Datei mit der Definition des Status erstellt. Ich kann in der Theorie verwechseln, aber es funktioniert in der Praxis

3

bemerkte einen Kommentar über IIS - habe es noch nicht hier sehen - aber das ist, wie ich meins arbeiten. Stellen Sie sicher, dass URL Rewrite 2.0 installiert ist.

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
<system.webServer> 
<rewrite> 
<rules> 
<rule name="AngularJS Routes" 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> 
</configuration>` 
+0

Hat super funktioniert, danke! – RandomUs1r

2

Wenn Sie Ihren Server nicht konfigurieren können, konfigurieren Sie Ihre web.xml mit der Refresh zu behandeln folgende, während der Benutzer auf einem html5 Push-Pfad ist.

<error-page> 
    <!-- Mapping a 404 when user refreshes with an html5 push route--> 
    <error-code>404</error-code> 
    <location>/index.html</location> 
</error-page> 
Verwandte Themen