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

问题描述:

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

I am currently writing a web application using angularjs, but I think this question applies to any client-side javascript framework that does routing on the client side (as angular does).

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

In a single-page app, what is the right way to deal with wrong URLs?

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

Looking at a few major sites, I see that gmail will redirect to the inbox if you type any random URL below https://mail.google.com/mail/. This happens server-side (with an http 300 code) or client-side, depending on whether the wrong path is before or after the # character. On the other hand, twitter shows a real HTTP 404 for any invalid URL. A third option would be to show a "soft" 404, a purely client-side error page.

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

These solutions seem appropriate for different situations. Twitter wants the links to twitter users and tweets to be real links, so people can share them, post them in news articles, etc, so it is important that invalid links be recognized as such (if I have a broken link to a tweet in my website, a simple crawl will tell me that). In gmail, on the other hand, you are not expected to share links into your inbox, and I'm not even sure if the links are really permanent/persistent: it seems the url updating mostly serves the purpose of browser history navigation within the single-page app. The third approach of giving soft errors might be appropriate for situations similar to gmail, but where there is no reasonable "default" page.

经过这么长的介绍,下面是一些具体问题:

After this long introduction, here are some specific questions:

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

如果您关心 SEO,angular.io 能够通过使用 noindex 元标记 表示软 404 状态,这将阻止爬虫抓取页面内容".显然它可以通过 JavaScript 添加到文档中.

If you care about SEO, one of the ways that angular.io was able to solve this problem (at least with Google anyway) is by using noindex meta tag "to indicate soft-404 status which will prevent crawlers from crawling the content of the page". Apparently it can be added to the document via JavaScript.

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

Alternatively, using JavaScript, you can redirect to a page that will respond with an actual HTTP 404 status code. Google understands JavaScript redirects just fine. Your original /does-not-exist page, when redirected to /404-error?from=does-not-exist, will be associated with the 404 status code returned by the server. The URL structure does not matter, only the status code and the redirect are important here.

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

Your other options are SSR (Nuxt.js, Next.js, Angular Universal, etc) or pre-rendering (prerender.io, puppeteer, etc) which Google calls dynamic rendering where you respond to search bot requests with a pre-rendered version while human users get your normal client-side rendered app.