问题
I have AngularJS webapp and start it with Tomcat 7. Using $locationProvider.html5Mode(true) I remove hash '#' from url
localhost:8080/App/#/login -> localhost:8080/App/login
But now, when I refresh localhost:8080/App/login I have 404 error. How to configure Tomcat7 for localhost:8080/App/login refresh?
app.config:
$urlRouterProvider.otherwise("/login/");
$stateProvider
.state('home', {
abstract: true,
templateUrl: 'dist/view/home.html',
controller: 'HomeCtrl'
});
$locationProvider.html5Mode(true);
index.html:
<head>
<meta charset="utf-8">
<script>
document.write('<base href="' + document.location + '" />');
</script>
</head>
回答1:
It's because when you do a full reload you always send a a request to the server with the current url. Since Angular has not loaded yet it can't handle the route, and the server doesn't know anything about what routes exist in angular and not
Without html5mode Angular uses fragmented urls of the type www.example.com/#/page. # was originally used for anchor-links so by convention the fragment part of the url is completely ignored by the server. To the server that above request would be the same as just www.example.com/, which is probably where you index.html is located. So reloading your page will in this case get your index.html, which will load Angular, which will in turn handle the fragment part of the url (#/page).
With html5mode however the fragment is hidden, and the url looks like a normal url, www.example.com/page. But when you reload the page the server doesn't get the fragment so it tries to find whatever is served under /page, which is probably nothing. Giving you a 404, Angular cannot load since index.html is not loaded, and you have a broken page.
The usual way to fix this is to have the server serve index.html under all urls that does not match a static asset (or the pattern of one). So if you request say an image it will find it and return it ok, but if you request /page (and it does not exist as a static asset) then it returns index.html. Then Angular will start, read the url and trigger the correct route.
I have only done this in nginx so I don't know how Tomcat would do it, but the principle should be the same.
回答2:
1) Download urlrewritefilter-4.0.3.jar
2) Create WEB-INF folder in root directory where index.html is present.
3) Create lib folder in WEB-INF & put downloaded jar file into it.
4) Create web.xml file in WEB-INF . Put following code into it.
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1" metadata complete="true">
<display-name>Welcome to Tomcat</display-name><description>Welcome to Tomcat</description><welcome-file-list><welcome-file>index.html</welcome-file></welcome-file-list>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class></filter><filter-mapping><filter-name>UrlRewriteFilter</filter-name><urlpattern>/*</url-pattern><dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher></filter-mapping></web-app>
5) Create urlrewrite.xml file WEB-INF
put following code into it
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE urlrewrite PUBLIC-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://tuckey.org/res/dtds/urlrewrite3.2.dtd"><urlrewrite>
<rule enabled="true">
<from>/[0-9_-a-zA-Z\/]+$</from>
<to>/%{context-path}/</to>
</rule>/urlrewrite>
This is using Tomcat 7 & Tucky's urlrewritefilter https://github.com/paultuckey/urlrewritefilter
@mhatch. To budle the routes to all go to index.html, you can try this rewrite rule :
<rule enabled="true">
<from>/[0-9_-a-zA-Z\/]+$</from>
<to>/%{context-path}/</to>
This worked for me.
回答3:
If you want to remove the hash (#), you must use rewrite function in server to serve the index.html for all path. If not, you will always receive 404 error. It's mean you can redirect the 404 to index.html.
Apache: add a rewrite rule to the .htaccess file as show here:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
NGinx: use try_files, as described in Front Controller Pattern Web Apps, modified to serve index.html:
try_files $uri $uri/ /index.html;
IIS: add a rewrite rule to web.config, similar to the one shown here:
<system .webserver="">
<rewrite>
<rules>
<rule name="Angular 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></add></conditions>
<action type="Rewrite" url="/">
</action></match></rule>
</rules>
</rewrite>
</system>
In tomcat, you can add it into the web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<error-page>
<error-code>404</error-code>
<location>/</location>
</error-page>
</web-app>
After redirect the web path to index.html, the HTML5 History API will be used in Angular JS to control the web route. Our main task here is just let index.html be called in server.
回答4:
1) AngularJS
$routeProvider
.when('/path', {
templateUrl: 'path.html',
});
$locationProvider
.html5Mode(true);
2) server side, just put .htaccess inside your root folder and paste this
ewriteEngine On
Options FollowSymLinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /#/$1 [L]
Cheers....
回答5:
Erik Honn gives a good explanation of the logic. Here's how I solved it using Jersey and Tomcat 7 with Tucky's urlrewritefilter https://github.com/paultuckey/urlrewritefilter
Add dependency using Maven or download jar.
<dependency> <groupId>org.tuckey</groupId> <artifactId>urlrewritefilter</artifactId> <version>4.0.3</version> </dependency>Add filter mappings to the web.xml file located in WEB-INF directory. This should be within the web-app tag.
<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>Create a file in WEB-INF called urlrewrite.xml and add rerouting to index.html
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd"> <!-- Configuration file for UrlRewriteFilter http://www.tuckey.org/urlrewrite/ --> <urlrewrite> <rule> <from>^/titles$</from> <to>index.html</to> </rule> <rule> <from>^/authors$</from> <to>index.html</to> </rule> <rule> <from>^/courses$</from> <to>index.html</to> </rule> <rule> <from>^/account$</from> <to>index.html</to> </rule> </urlrewrite>
Don't forget to relaunch so that the xml is configured. It would be great if someone knew a way to bundle the routes to all go to index.html rather than having to set individual rules.
回答6:
Just write this in htaccess
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.php [L]
I dont have an index.html i have index.php so i wrote index.php instead of index.html
Cheers!
回答7:
I recently found a solution to this issue that doesn't involve switching to Apache2 with a .htaccess file.
In web.xml:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/rewrite-404.jsp</location>
</error-page>
Then create a new file in WebContent called rewrite-404.jsp:
<% response.setStatus(HttpServletResponse.SC_OK); %>
<%@ include file="index.html" %>
This will cause existing files in WebContent to be served as usual, and all requests that would normally return a 404 error to return index.html instead with a 200 (OK) response code.
来源:https://stackoverflow.com/questions/32887222/angularjs-remove-and-have-error-when-refresh-page