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

Java AngularJS HTML5模式-在没有服务器特定更改的情况下,直接链接如何工作?,java,angularjs,web.xml,single-page-application,Java,Angularjs,Web.xml,Single Page Application,注:这一问题也可以改为: 如何支持无hashbang客户端mvc框架的书签 在Java中 我正在将一个使用hashtags的angular应用程序转换为HTML5模式。我成功地设置了 $locationProvider.html5Mode(true); 并且登录页面(index.html)中的所有链接都可以正常工作 问题是,如果直接引用部分URL,自然会得到404,因为服务器端点定义没有耦合到客户端定义的路由 因此,如果没有HTML5,我们会得到不利于SEO的hashbang,但有了它,除了登

注:这一问题也可以改为:

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

我正在将一个使用
hashtags
的angular应用程序转换为
HTML5模式
。我成功地设置了

$locationProvider.html5Mode(true);
并且登录页面(index.html)中的所有链接都可以正常工作

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

因此,如果没有HTML5,我们会得到不利于SEO的hashbang,但有了它,除了登录页面(引导页面)之外,我们不能为任何内容添加书签

如果首先请求默认登录页(index.html),它为什么会起作用htpp://mydomain.com/ :

  • 浏览器从服务器请求index.html
  • 服务器返回index.html,浏览器加载角度框架
  • URL更改被发送到客户端路由器,并加载适当的部分/s
  • 如果直接从浏览器请求(ie),为什么它不起作用:

  • 浏览器从服务器请求mydomain/foo
  • 资源不存在
  • 服务器返回404
  • 这个故事缺少了一些东西,我只是不知道是什么。以下是我能看到的唯一两个答案

    • 这是设计的。它应该是这样工作的吗?用户必须始终登录到客户机MVC框架的引导页面(通常是index.html),然后从那里导航。这并不理想,因为无法保存状态,并且无法将其添加到书签。。。更不用说爬行了
    • 服务器解决方案。这是通过服务器端技巧解决的吗?例如,在所有请求上,返回index.html并立即使用附加上下文调用router。如果是这样的话,这与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>
        
        
        index.jsp
        静态servlet
        /index.jsp
        静态servlet
        /应用程序
        
        而index.jsp看起来就像:

        <%@ include file="index.html" %>
        
        
        
        并将以下内容添加到index.html内的标记中:

        <base href="/app" />
        

        您链接到并放置在用户地址栏中的URL应该引用服务器上的有效内容,如果可能,它们应该引用正确的内容。当然,您可以为每个URL提供相同的页面,让客户机代码启动并加载真正的内容,事情的运行方式与哈希URL世界中的运行方式基本相同。事实上,这是最简单的编码方式。但它也被称为“打破互联网”,这就是为什么HTML5和历史API为您提供了一种链接到语义正确的URL的方法


        作为一个小示例,如果转到并单击“示例”,客户端代码将在不离开页面的情况下将“示例”目录加载到文件浏览器中,URL栏将显示为。如果直接转到,则“示例”目录的内容将直接发送到浏览器,而无需客户端代码中介。是的,这是很难做到的,在“单页应用程序”中可能不可能做到,但只要有可能,这是正确的做法。

        我花了一些时间在我的PHP网站上思考这个问题。我将所有服务器端代码挂起/api路由,以使其与应用程序分离。以下是我通过更新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框架写下了我是如何做到这一点的。您应该在主html文件的头部指定url基()最后一点是解决方案。在服务器端实现某种过滤器,为所有应用程序URL提供index.html。不需要更多了。路由器将自动在位置栏中显示与URL关联的页面。这似乎应该包含在AngularJS文档中。类似于“哦,是的,当您打开HTML5模式时,您还需要进行服务器端更改,以确保包含基本uri的所有请求都返回引导html(即index.html)资源。”我同意您的看法。问题在于angular是一个纯粹的客户端框架,而服务器端配置的方式取决于服务器端使用的技术,angular对此并不关心。我的猜测是,他们发现这一点很明显,不必提及。鉴于angular的复杂性,我希望它能被经验丰富的开发人员使用,他们知道服务器端必须做什么。我发现了我认为最好的解决方案,正如JB所说,这是我上面的第二个要点。事实证明,Angular在他们的文档中提到了服务器端支持要求:“使用(html5)模式需要在服务器端重写URL,基本上你必须重写所有指向应用程序入口点的链接(例如index.html)”“理解这个宗教论点,但它基本上是说“不要做单页应用。”或者“如果您创建单页应用程序,请确保也有服务器端MVC实现,这样您就不会破坏互联网。“@rob我不会撒谎,单页应用是一种大脑损伤。在不远的将来,我们会像今天看到Flash驱动的网站一样看到它们。好吧,现在我们变得富有哲理了,我明白你的观点。但它们本质上不同于flash(和小程序),因为它们不是专有的。如果web应用程序开发