AngularJS HTML5模式 - 直接链接如何在没有服务器特定更改的情况下工作?

Rob*_*ian 46 java web.xml angularjs single-page-application

注意:这个问题也可以是:

如何在Java中支持hashbang-less客户端mvc框架的书签.

我过渡使用的角度应用hashtags到一个是html5mode.我成功了

$locationProvider.html5Mode(true);
Run Code Online (Sandbox Code Playgroud)

来自着陆页(index.html)的所有链接都可以正常工作.

问题是,如果直接引用部分URL,我自然会得到404,因为服务器端点定义没有耦合到客户端定义的路由.

因此,如果没有HTML5,我们会得到非SEO友好的hashbang,但是有了它,我们就不能为登陆页面(bootstraps angular的页面)以外的任何内容添加书签.

如果首先请求默认登录页面(index.html),为什么它可以工作,即htpp://mydomain.com/:

  1. 浏览器从服务器请求index.html
  2. 服务器返回index.html,浏览器加载角度框架
  3. URL更改将发送到客户端路由器并加载正确的部分.

如果直接从浏览器请求(即)http://mydomain.com/foo,为什么它不起作用:

  1. 浏览器从服务器请求mydomain/foo.
  2. 资源不存在
  3. 服务器返回404

这个故事遗漏了一些东西,我只是不知道是什么.以下是我能看到的唯一两个答案......

  • 这是设计的. 这是它应该如何工作?用户必须始终登陆客户端MVC框架的引导页面(通常是index.html),然后从那里导航.这不是理想的,因为状态无法保存,无法书签......更不用说抓取了.
  • 服务器方案. 这是否与服务器端技巧有关?例如,在所有请求上,返回index.html并立即使用其他上下文调用路由器.如果是这样,这违背了AngularJS完全是客户端并且看起来像黑客的目标.

Rob*_*ian 39

事实上,AngularJS文档确实提到了这一点

服务器端使用此模式需要在服务器端重写URL,基本上您必须重写所有链接到应用程序的入口点(例如index.html)

在这种情况下,一个基于Java的解决方案是告诉服务器"将所有URL映射到index.html".这可以在任何HTTP服务器或容器中完成.我使用Java/Servet实现了这个,因为我希望我的应用程序与HTTP服务器无关(即Apache与NginX或仅Tomcat/JBoss).

在web.xml中:

  <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
      <servlet-name>StaticServlet</servlet-name>
      <jsp-file>/index.jsp</jsp-file>
  </servlet>

  <servlet-mapping>
      <servlet-name>StaticServlet</servlet-name>
      <url-pattern>/app</url-pattern>
  </servlet-mapping>
Run Code Online (Sandbox Code Playgroud)

而index.jsp看起来像:

<%@ include file="index.html" %>
Run Code Online (Sandbox Code Playgroud)

并将以下内容添加到index.html中的标记中:

<base href="/app" />
Run Code Online (Sandbox Code Playgroud)