AngularJS HTML5 Mode - 如何在没有服务器特定更改的情况下使用直接链接?

注意:这个问题也可以读作:

如何在Java中支持无哈希邦客户端MVC框架的书签。

我正在将一个使用的角度应用程序转换为.我已成功设置hashtagshtml5mode

$locationProvider.html5Mode(true);

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

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

因此,如果没有HTML5,我们会得到非SEO友好的哈希邦,但是有了它,除了登录页面(引导角度的页面)之外,我们无法为其他任何内容添加书签。

如果首先请求默认着陆页(索引.html),即 htpp://mydomain.example/,为什么它有效:

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

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

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

这个故事中缺少了一些东西,我只是不知道是什么。以下是我能看到的仅有的两个答案...

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

答案 1

AngularJS文档确实提到了这一点。

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

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

在网络.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>

索引.jsp看起来像这样:

<%@ include file="index.html" %>

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

<base href="/app" />

答案 2

我花了一些时间为我的PHP网站考虑这个问题。我将所有服务器端代码挂在 /api 路由上,以使其与 Angular 分开。以下是我通过更新apache配置提出的解决方案:

RewriteEngine on
#let the php framework do its thing
RewriteRule ^(api/.*)$ index.php?url=$1 [QSA,L,NC]
#let angular do its thing
RewriteCond %{REQUEST_FILENAME} !-f      
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.html [NC,L]

我写了我如何使用Flight PHP框架来解决这个问题 http://www.awnage.com/2013/10/10/taking-flight-with-angularjs/


推荐