我正在编写一个基本上是一系列连续页面的网站。非限定 URL 指向最后一页,限定 URL 指向特定页面。所以我们有:
- http://example.com/ -> 最后一页
- http://example.com/3 -> 第 3 页
我有以下要求:
- 我希望页面由 AJAX 动态加载。用户可能会在短时间内顺序浏览许多连续页面,我想避免重新加载和重绘(并添加某种 JavaScript 预取相邻页面以加快导航速度)
- 我希望这些页面可以添加书签
- 我希望页面可抓取
- 我希望它适用于大多数用户。
所以,我想出了以下方案:
- 存档页面的标准规范 URL 是http://example.com/3。通过此 URL 访问的页面是完全可读的,无论是否安装了 JavaScript。如果 JavaScript 不可用,则指向其他页面的链接是正常链接,并且一切都以老式的方式运行。这也适用于爬虫。
- 如果可以使用 JavaScript 和历史操作(pushState 和 replaceState)的浏览器访问此类 URL,则在访问其他页面的链接时,内容会使用 AJAX 动态更新。然后浏览器历史记录由 JavaScript 更新。
- 如果 JavaScript 可用但历史操作不可用的浏览器访问该站点,则在访问 http://example.com/3 时使用JavaScript 将用户重定向到http://example.com/#!3 . 访问主页http://example.com时不会发生重定向。然后使用散列更改事件完成导航。
- 如果爬虫试图通过外部链接访问http://example.com/#!3,它实际上会请求http://example.com/?_escaped_fragment_=3 ( 1 )。对于此类 URL,网络服务器将发出永久重定向到http://example.com/3,然后将被正确抓取。
在这里一切看起来都很好,但是,让我们看看所有可能的情况:
1.没有JavaScript浏览器
1.1。没有 JavaScript 浏览器访问根 URL
按预期工作。
1.2. 没有 JavaScript 浏览器访问规范 URL
按预期工作。
1.3. 没有 JavaScript 浏览器访问 shebang URL
默默失败!用户得到最后一页而不是第 3 页。
2. 爬虫
2.1。爬虫访问根 URL
按预期工作。
2.2. 爬虫访问规范 URL
按预期工作。
2.3. 爬虫访问shebang URL
爬虫实际上请求http://example.com/?_escaped_fragment_=3,并被重定向到规范 URL。这是对 Web 服务器的一个额外请求,但这没什么大不了的(不会从数据库中获取额外的页面并返回给用户)。
3.旧浏览器
3.1。旧浏览器访问根 URL
其他页面的链接被它们的 shebang 版本所取代。然后通过 AJAX 顺利完成导航。
3.2. 旧浏览器访问规范 URL
用户被重定向到 shebang URL。问题:服务器实际上会获取并服务页面 3 次!
- http://example.com/3 <- 完全由服务器提供服务
- JavaScript 发出重定向到http://example.com/#!3
- 服务器只看到http://example.com/,并提供最后一页
- JSON 用于(再次)获取第 3 页并替换页面上的内容。
3.3. 老浏览器访问shebang URL
不需要重定向,但最后一页有额外的负载!
- 用户访问http://example.com/#!3
- 服务器只看到http://example.com/,并提供最后一页
- JSON 用于获取页面 3 并替换页面上的内容。
4.现代浏览器
4.1。现代浏览器访问根 URL
4.2. 现代浏览器访问规范 URL
这两种情况都没有问题。导航由 AJAX 完成,规范的 URL 被推送到历史记录。
4.3. 现代浏览器访问shebang URL
URL 被修改为规范 URL。内容由 AJAX 加载。和以前一样,问题是这会导致服务器对最后一页产生额外的负载。
所以,总结一下:
- 该解决方案基本上可以工作
- 但是当使用 shebang URL 时,在大多数情况下,它会导致最后一页的不必要加载,因为服务器永远不会知道它是否需要服务器最后一页,或者这是否实际上是 shebang 请求的一部分。
我的问题是:有人知道如何避免这些额外的页面加载吗?有什么好的做法可以解决这样的问题吗?