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

注意:这个问题也可以这样写:

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

我正在转换一个angular度的应用程序,使用hashtags html5mode 。 我已经成功设置

 $locationProvider.html5Mode(true); 

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

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

因此,如果没有HTML5,我们会获得非SEO友好的hashbangs,但是对于其他目标网页(bootstrapsangular色的页面),我们不能添加书签。

为什么如果首先请求默认login页面(index.html),即htpp://mydomain.com/:

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

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

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

这个故事中缺less的东西,我只是不知道。 这是我能看到的唯一的两个答案

  • 这是devise。 这是应该如何工作? 用户必须始终登陆客户端MVC框架的引导页面(通常是index.html),然后从那里导航。 这是不理想的,因为国家不能保存,没有办法书签…更不用说抓取。
  • 服务器scheme。 这是一个服务器端技巧解决? 例如,在所有的请求中,返回index.html并立即调用具有额外上下文的路由器。 如果是这样,这是违背AngularJS完全客户端的目标,并且看起来像一个黑客攻击。

AngularJS文档确实提到了这一点

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

在这种情况下,一个基于Java的解决scheme是告诉服务器“将所有的URL映射到index.html”。 这可以在任何HTTP服务器或容器中完成。 我使用Java / Servet实现了这个function,因为我希望我的应用程序能够与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> 

和index.jsp只是看起来像:

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

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

 <base href="/app" /> 

我花了一些时间来思考我的PHP网站。 我将所有的服务器端代码挂在/ apipath上,以保持与Angular的独立。 这是我通过更新我的Apacheconfiguration提出的解决scheme:

 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] 

我写了如何使用飞行PHP框架在http://www.awnage.com/2013/10/10/taking-flight-with-angularjs/

您链接到并放置在用户地址栏中的URL应该引用服务器上的有效内容,如果可能的话,应该引用正确的内容。 当然,你可以为每个URL服务相同的页面,并让客户端代码去掉并加载真实的内容,而且事情的function与他们在hash-URL世界中的做法非常相似。 事实上,这是最简单的代码方式。 但它也有资格作为“打破互联网”,这就是为什么HTML5和历史API给你一种链接到语义上正确的 URL的方式。

作为一个小例子,如果你去https://github.com/kriskowal/q然后你点击“examples”,客户端代码将直接加载文件浏览器的“examples”,而不离开页面,url栏会显示https://github.com/kriskowal/q/tree/master/examples 。 如果直接访问https://github.com/kriskowal/q/tree/master/examples ,则会将“examples”目录的内容直接发送到您的浏览器,而无需客户端代码中介。 是的,这是很难做到的,也许在一个“单页面应用程序”是不可能的,但是任何时候都是可行的。