问题描述
注意:这个问题也可以写成:
如何支持hashbang-less客户端mvc框架的书签在 Java 中.
我正在将使用 hashtags
的 Angular 应用转换为 html5mode
.我已经成功设置
I am transitioning an angular app that uses hashtags
to one that is html5mode
. I have successfully set
$locationProvider.html5Mode(true);
并且来自着陆页 (index.html) 的所有链接都可以正常工作.
And all links from the landing page (index.html) work fine.
问题是,如果直接引用部分 url,我自然会得到 404,因为服务器端点定义没有耦合到客户端定义的路由.
The problem is, if partial urls are referenced directly, I get a 404, naturally, since the server endpoint definitions aren't coupled to client side-defined routes.
因此,如果没有 HTML5,我们将获得对 SEO 不友好的 hashbang,但有了它,我们无法为着陆页(引导 angular 的页面)以外的任何内容添加书签.
So without HTML5 we get non-SEO friendly hashbangs, but with it we cannot bookmark anything other than the landing page (the page that bootstraps angular).
如果首先请求默认登录页面 (index.html),即 htpp://mydomain.com/,为什么会起作用:
Why it works if requesting default landing page (index.html) first, ie htpp://mydomain.com/ :
- 浏览器从服务器请求 index.html
- 服务器返回index.html,浏览器加载angular框架
- 将 URL 更改发送到客户端路由器并加载正确的部分.
如果(即)http://mydomain.com/foo 是直接从浏览器请求的,为什么它不起作用:
Why it doesn't work if (ie) http://mydomain.com/foo is requested directly from the browser:
- 浏览器从服务器请求 mydomain/foo.
- 资源不存在
- 服务器返回 404
这个故事缺少一些东西,我只是不知道是什么.这是我能看到的仅有的两个答案...
Something is missing from this story, I just don't know what. Here are the only two answers I can see...
- 这是设计使然.这是应该的工作方式吗?用户必须始终登陆客户端 MVC 框架的引导页面(通常是 index.html),然后从那里导航.这并不理想,因为无法保存状态并且无法添加书签……更不用说爬行了.
- 服务器解决方案.这是通过服务器端技巧解决的吗?例如,对所有请求,返回 index.html 并立即调用具有附加上下文的路由器.如果是这样,这与 AngularJS 完全是客户端的目标背道而驰,而且看起来像是一种黑客攻击.
- It's by design. Is this how it is supposed to work? That users must always land on the client MVC framework's bootstrap page (usually index.html), and then navigate from there. This is not ideal because state cannot be saved and there is no way to bookmark... not to mention crawling.
- Server solution. Is this worked around with a server side trick? For example, on all requests, return index.html and immediately call router with additional context. If so, this is against the objective that AngularJS is completely client-side and seems like a hack.
推荐答案
AngularJS 文档 实际上确实提到了这一点
The AngularJS documentation does in fact mention this
服务器端使用这种模式需要在服务器端重写URL,基本上你必须重写所有链接到你的入口点应用程序(例如 index.html)
在这种情况下,一种基于 Java 的解决方案是告诉服务器将所有 url 映射到 index.html".这可以在任何 HTTP 服务器或容器中完成.我使用 Java/Servet 实现了这一点,因为我希望我的应用程序与 HTTP 服务器无关(即 Apache 与 NginX,或仅 Tomcat/JBoss).
In this case, one Java-based solution is to tell the server "map all urls to index.html." This can be done in any HTTP Server or container. I implemented this using Java/Servet since I want my application to be HTTP server agnostic (ie Apache versus NginX, or Tomcat/JBoss only).
在 web.xml 中:
In 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 看起来就像:
And index.jsp simply looks like:
<%@ include file="index.html" %>
并将以下内容添加到 index.html 中的标记:
And add the following to the tag within index.html:
<base href="/app" />
这篇关于AngularJS HTML5 模式 - 直接链接如何在没有服务器特定更改的情况下工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!