AngularJS删除#并在刷新页面时出错

时间:2015-10-01 12:07:22

标签: angularjs tomcat7

我有AngularJS webapp并以 Tomcat 7 启动它。使用$locationProvider.html5Mode(true)我删除哈希'#'来自网址

localhost:8080/App/#/login -> localhost:8080/App/login

但现在,当我刷新localhost:8080/App/login时,我有404 error。如何为localhost:8080/App/login刷新配置Tomcat7?

的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 个答案:

答案 0 :(得分:9)

这是因为当您执行完全重新加载时,您始终会使用当前网址向服务器发送请求。由于Angular尚未加载,它无法处理路由,服务器也不知道角度存在哪些路由,而不是

没有html5mode Angular使用www.example.com/#/page类型的碎片网址。 #最初用于锚链接,因此按照惯例,服务器完全忽略url的片段部分。对于上述请求的服务器将与www.example.com/相同,这可能是index.html所在的位置。因此,在这种情况下重新加载页面将获得index.html,它将加载Angular,后者将依次处理url的片段部分(#/ page)。

使用html5mode但片段是隐藏的,并且网址看起来像普通网址www.example.com/page。但是当你重新加载页面时,服务器没有得到片段,所以它试图找到在/ page下提供的任何东西,这可能没什么。给你一个404,Angular无法加载,因为没有加载index.html,并且你的页面已经坏了。

解决此问题的常用方法是让服务器在所有与静态资产(或模式的模式)不匹配的网址下提供index.html。因此,如果您请求说出一个图像,它将找到它并将其返回正常,但如果您请求/页面(并且它不作为静态资产存在),则返回index.html。然后Angular将启动,读取url并触发正确的路径。

我只在nginx中做过这个,所以我不知道Tomcat会怎么做,但原则应该是一样的。

答案 1 :(得分:1)

1)下载urlrewritefilter-4.0.3.jar

2)在存在index.html的根目录中创建WEB-INF文件夹。

3)在WEB-INF&amp; amp;中创建lib文件夹。将下载的jar文件放入其中。

4)在WEB-INF中创建web.xml文件。将以下代码放入其中。

<?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)创建urlrewrite.xml文件WEB-INF

将以下代码放入其中

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

这是使用Tomcat 7&amp; Tucky的urlrewritefilter https://github.com/paultuckey/urlrewritefilter

@mhatch。要将所有路由发布到index.html,您可以尝试使用此重写规则:

<rule enabled="true">
    <from>/[0-9_-a-zA-Z\/]+$</from>

    <to>/%{context-path}/</to>

这对我有用。

答案 2 :(得分:1)

如果要删除哈希(#),必须在服务器中使用重写功能为所有路径提供index.html。如果没有,您将始终收到404错误。这意味着您可以将404重定向到index.html

Apache:.htaccess文件中添加重写规则,如下所示:

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:使用try_files,如前控制器模式网络应用中所述,已修改为提供index.html

try_files $uri $uri/ /index.html;

IIS:web.config添加重写规则,类似于此处显示的规则:

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

tomcat 中,您可以将其添加到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>

将网络路径重定向到index.html后,HTML5历史记录API将在Angular JS中用于控制网络路由。我们的主要任务是让index.html在服务器中调用。

答案 3 :(得分:0)

1)AngularJS

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

2)服务器端,只需将.htaccess放入根文件夹并粘贴

ewriteEngine On 
Options FollowSymLinks

RewriteBase /

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

...干杯

答案 4 :(得分:0)

Erik Honn对逻辑作出了很好的解释。这是我用Tucky的urlrewritefilter https://github.com/paultuckey/urlrewritefilter

使用Jersey和Tomcat 7解决它的方法
  1. 使用Maven添加依赖项或下载jar。

    <dependency>
        <groupId>org.tuckey</groupId>
        <artifactId>urlrewritefilter</artifactId>
        <version>4.0.3</version>
    </dependency>
    
  2. 将过滤器映射添加到位于WEB-INF目录中的web.xml文件。这应该在web-app标签内。

    <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>
    
  3. 在WEB-INF中创建一个名为urlrewrite.xml的文件,并将重新路由添加到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>
    
  4. 不要忘记重新启动以便配置xml。如果有人知道如何将路由捆绑到所有转到index.html而不必设置单独的规则,那就太棒了。

答案 5 :(得分:0)

只需在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]

我没有index.html我有index.php所以我写了index.php而不是index.html

干杯!

答案 6 :(得分:0)

我最近找到了这个问题的解决方案,不涉及使用.htaccess文件切换到Apache2。

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

然后在WebContent中创建一个名为rewrite-404.jsp的新文件:

<% response.setStatus(HttpServletResponse.SC_OK); %>
<%@ include file="index.html" %>

这将导致WebContent中的现有文件照常提供,并且所有通常返回404错误的请求都返回index.html而不是200(OK)响应代码。