61

我目前正在使用 angularjs 编写一个 Web 应用程序,但我认为这个问题适用于任何在客户端进行路由的客户端 javascript 框架(就像 angular 一样)。

在单页应用中,处理错误 URL 的正确方法是什么?

查看一些主要网站,我发现如果您在https://mail.google.com/mail/下方键入任何随机 URL,gmail 将重定向到收件箱。这发生在服务器端(使用 http 300 代码)或客户端,具体取决于错误路径是在 # 字符之前还是之后。另一方面,twitter 显示任何无效 URL 的真实 HTTP 404。第三个选项是显示一个“软”404,一个纯粹的客户端错误页面。

这些解决方案似乎适用于不同的情况。Twitter 希望到 twitter 用户和推文的链接是真正的链接,因此人们可以分享它们,将它们发布在新闻文章中等,因此重要的是要识别无效链接(如果我在我的网站,一个简单的抓取就会告诉我)。另一方面,在 gmail 中,您不应该将链接共享到您的收件箱中,而且我什至不确定这些链接是否真的是永久的/持久的:似乎 url 更新主要用于浏览器历史导航中的目的单页应用。第三种给出软错误的方法可能适用于类似于 gmail 的情况,但没有合理的“默认”页面。

经过这么长的介绍,这里有一些具体的问题:

  • 提供“软”错误页面而不是 404 错误是否可以接受,或者如果 url 无效,单页应用程序是否应该始终重定向到真正的 404?
  • Gmail 的代码可能完全没有错误,但如果它确实存在导致无效链接最终重定向回收件箱的错误,那可能比错误页面更让用户感到困惑。对于大多数 Web 应用程序,它们的测试不如 gmail 好,显示错误页面会更好吗?
  • 要为单页应用程序实现真正的 404,似乎有必要在服务器端复制路由逻辑。有没有办法解决?
  • 当重定向到 404 时,我认为用户应该能够看到导致错误的 URL,可能在 URL 栏中。使用 html5 history api,我认为这可以通过简单地触发当前页面的重新加载(使用错误的 url),结合上面提到的服务器端路由来完成。对于不支持此功能或使用 hashbang 表示法的浏览器,这似乎是不可能的。支持所有浏览器的最佳方式是什么?
4

2 回答 2

8

如果您关心 SEO,angular.io 能够解决此问题的方法之一(至少与 Google 一样)是使用noindex 元标记“来指示软 404 状态,这将阻止爬虫爬取内容页”。显然它可以通过 JavaScript 添加到文档中。

或者,使用 JavaScript,您可以重定向到将响应实际 HTTP 404 状态代码的页面。Google 可以很好地理解 JavaScript 重定向。您的原始/does-not-exist页面在重定向到 时/404-error?from=does-not-exist,将与服务器返回的 404 状态码相关联。URL 结构无关紧要,这里只有状态码和重定向很重要。

您的其他选项是 SSR(Nuxt.js、Next.js、Angular Universal 等)或预渲染(prerender.io、puppeteer 等),Google 称之为动态渲染,您可以使用预渲染版本响应搜索机器人请求而人类用户则获得您正常的客户端渲染应用程序。

于 2018-11-20T20:19:53.450 回答
5

tl;dr:如果您关心 SEO,请放弃 hashbang 支持并选择类似PJAX的行为。

您是在制作应用程序还是网站?如果您需要返回网站,404以免混淆 google。它需要是真实的404,而不仅仅是显示未找到页面的消息(即200带有“未找到页面”的消息非常糟糕)。另外,您希望支持哪些浏览器?

我的观点是应该避免整个 hashbang 服务器端渲染(即讨厌的 Google SEO #!hack)。如果不支持 pushstate 的浏览器的 URL 发生更改(不是哈希更改),请使用真正的 pushstate 或重新呈现整个页面。

现在这很重要的原因是 a#!永远不应该返回 a404因为它没有意义并且不可能模仿服务器端,因为服务器永远不会在#!没有运行 Javascript 的情况下得到什么。

因此,如果您真的关心 SEO,我会做类似 PJAX 的事情,并且只使用真正的 pushstate 进行路由,然后就无法使用旧的 web 1.0。因此,我建议您共享的链接确实是404不应该有的(只要页面内容不发生剧烈变化,#!传统上就可以了)。#

最后,这404主要不是问题,而是30X重定向响应。那是因为浏览器将自动处理重定向,因此您的 Javascript AJAX 调用将永远不会看到 a 30X(他们将获得重定向响应......即 200)。要处理30X响应,您必须为每个请求发回一个标头,以指示重定向的 URL 是/曾经是什么(即您被重定向到什么),这样您就不会弄乱 Pushstate 历史记录。

当然,如果您也需要像 Twitter 那样支持 hashbang(而且它们甚至杀死了 hashbang),您可以利用 Google Sitemapsrel=nofollow来尝试减轻不良的 SEO。

于 2013-02-09T15:57:16.357 回答