-1

我正在我的本地机器上创建一个单页应用程序 (SPA),但在文档根目录下几个级别。因此,例如,我的索引页将位于http://localhost/projects/foo/index.html.

我正在使用Davis.js通过历史 API 进行客户端路由,它建议对其路由使用绝对 URL。例如<a href="/hello/world">触发/hello/world路由。

这是一个问题,因为当您单击位于 上的链接时http://localhost/projects/foo/index.html,它会将 URL 更改为http://localhost/hello/world,这显然是不正确的,即使应用程序继续正常运行(因为您实际上从未离开过该页面)。但是,刷新页面,您将收到 404 错误,因为该文件http://localhost/hello/world不存在。

使用相对链接,like<a href="hello/world">更接近标记。单击该链接会将 URL 更改为http://localhost/projects/foo/hello/world,但不会触发路由/hello/world。再次单击相同的链接,您会发现自己位于http://localhost/projects/foo/hello/hello/world(double hello)。同样,不是理想的行为。

现在,Davis 正在匹配来自域根的路由,所以/hello/world只会在 url 为http://somewhere.tld/hello/world. 但即使我直接从文档根目录中提供服务,仍然/hello/world 存在实际不存在的问题。

目前,我当前的解决方案是强制 Davis 使用基于哈希的路由而不是基于路径:http://localhost/projects/foo/index.html#/hello/world. 这可以 100% 正常工作,因为浏览器将始终加载index.html,Davis 将始终看到/hello/world. 此外,只要用户打开了 Javascript,包含该哈希片段的链接将始终有效。(我不担心那种情况)

我可以看到的一种解决方案是有一个基本 URL http://localhost/projects/foo/,让服务器将该目录中的所有请求重写为index.html,并让所有链接和路由指向并匹配基本 url + 片段(如http://localhost/projects/foo/hello/world)。所以从技术上讲,所有这些 URL确实存在,它们都指向同一个文件。然而,这需要(a)一个能够重写 URL 的服务器为 SPA 服务(url-hash 解决方案甚至不需要服务器,只需要一个浏览器)和(b) SPA 跟踪它的“位置”是相对于文档根目录的(这对我来说是一件非常糟糕的事情)。

所以我的问题是,做客户端路由的正确方法是什么,与应用程序在服务器上的位置无关,最好不需要静态托管以外的服务器端技术。

4

2 回答 2

1

我认为最好的方法是让您使用 Davis 定义的任何客户端路由也可以在服务器上使用。因此,如果您有一个客户端路由,/foo/bar那么理想情况下,服务器应该能够对相同的路由做出明智的响应。

这通常比听起来简单,并且如果您使用的是与语言无关的模板语言(例如 mustache),则不必涉及大量重复。

如果这是不可能的,那么有一些解决方法,以便服务器为您的客户端仅返回 404 以外的其他路由。然而,这些对我来说总是感觉像是解决方法而不是解决方案。显然,答案取决于您正在构建什么样的应用程序。

至于在相关路线上使用 Davis,我承认这是我从未使用过的东西,因此不能说它的支持程度如何。戴维斯的设计中没有任何特别的东西会阻止它工作。

但是,我刚刚在浏览器中使用了 pushState api,它的相对路径似乎确实有些奇怪。

于 2012-09-02T21:50:06.760 回答
1

我在单页应用程序和客户端路由方面也有类似的经历。

在稍微考虑了这个问题之后,我最终意识到,为了 SEO,您实际上会希望您的服务器在 Davis 建议的绝对 url 处呈现内容。这样,Google 抓取工具实际上可以继续抓取您的网站,就好像它不是单页应用程序一样。

如果你说你不能做任何服务器端的技术,那么问题就会困难得多。您提出的解决方案似乎都很合理。

您可能还希望在此链接上阅读有关Google 的爬虫规范的信息

于 2012-08-10T00:56:00.730 回答