AngularJS remove # and have error when refresh pag

2020-06-18 00:56发布

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>

7条回答
Anthone
2楼-- · 2020-06-18 01:28

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!

查看更多
叛逆
3楼-- · 2020-06-18 01:28

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.

查看更多
Luminary・发光体
4楼-- · 2020-06-18 01:37

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.

查看更多
家丑人穷心不美
5楼-- · 2020-06-18 01:37

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.

查看更多
等我变得足够好
6楼-- · 2020-06-18 01:41

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....

查看更多
淡お忘
7楼-- · 2020-06-18 01:42

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.

查看更多
登录 后发表回答