zoukankan      html  css  js  c++  java
  • 【白话科普】上网时遇到的 404 是什么意思?

    随着网络时代的发展与进步,我们的学习工作和生活早已离不开互联网,智能家居、网上购物、日常出行都需要互联网的支持。互联网切切实实地给生活带来了诸多便利。

    那大家有没有碰到过这么一个情况呢?当我们在使用手机或者电脑浏览一些信息的时候,或者在搜索引擎中搜索资料,点击搜索结果跳转后,浏览器跳出一个 404 Not Found 的空白页。

    相信各位老网民都很熟悉“404”这个数字了,这个错误代码代表着服务器未找到文件,通常出访问的页面已经被更改或者移除,或是输入了错误的访问地址错误。

    那为什么用 404 而不是其他的数字来代表访问资源不存在呢?互联网上对 404 的诞生有这么一个“传说”。据传在第三次科技革命前,整个互联网的形态就像是一个大型的中央数据库,并设置在一个叫 404 的房间里。那个时候,所有的互联网访问请求都由人工手动完成,若在 404 房间中没有找到请求者所需要的文件,或是由于请求者写错了文件编号,工作人员就会返回一个“Room 404 : File Not Found”的信息。

    当然,经实际考证后发现传说中的 Room 404 其实并不存在,而 404 的真正来源则要从互联网之本 -HTTP 协议说起。

    状态码的由来

    众所周知,互联网的建立打破了地域限制,通过浏览器与服务器之间的交流让我们足不出户知天下。而浏览器与服务器之间的交流则是通过 HTTP 协议。

    HTTP(Hypertext Transfer Protocol),超文本传输协议,它是应用层协议。由于其简捷、快速的方式,适用于分布式和合作式超媒体信息系统。自 1990 年起应用于万维网(WWW)全球信息服务系统。

    用户上网的过程,就是浏览器通过 HTTP 协议向服务端发送请求,然后将服务端主机上的内容显示到本地。

    支撑着 HTTP 协议工作的是 TCP/IP 协议这个模范打工人,它负责了底层的数据传输工作。单从这一点上来看,所谓的“超文本传输协议”其实和传输没什么联系,有点名不副实。那为什么 HTTP 还被称为传输协议呢?答案就是它是传输报文内容的。

    HTTP 协议在规范文档里详细定义了报文的格式,规定了组成部分,解析规则,还有处理策略,所以可以在 TCP/IP 层之上实现除了数据传输外,更灵活丰富的功能。

    TCP 的协议报文,在实际要传输的数据之前附加了一个 20 字节的头部数据,存储 TCP 协议必须的额外信息,例如发送方的端口号、接收方的端口号、包序号、标志位等等。有了这个附加的 TCP 头,数据包才能够正确传输,到了目的地后把头部去掉,就可以拿到真正的数据。

    HTTP 协议也需要在实际传输的数据前附加这类头数据,不过与 TCP 不同的是,它是一个“纯文本”的协议,头数据都是 ASCII 码的文本,可以很容易地用肉眼阅读,不用借助程序解析也能够看懂。

    HTTP 协议的请求报文和响应报文的结构基本相同,主要由三大部分组成:

    • 状态行(status line):描述响应的基本信息,也就是服务器响应的状态;

    • 头部字段集合(header):使用 key-value 形式更详细地说明报文;

    • 消息正文(entity):实际响应的数据,它不一定是纯文本,可以是图片、视频等二进制数据。

    其中状态行和头部字段经常又合称为“响应头”,消息正文又称为“实体”,与“header”对应,很多时候直接称为“body”。

    HTTP 协议规定报文必须有 header,但可以没有 body,且在 header 之后必须要有一个“空行”,也就是“CRLF”,十六进制的“0D0A”。

    完整 HTTP 响应报文

    以又拍云存储接口文件上传完毕后返回的响应报头为例,第一行“HTTP/2 200 OK”为状态行,由三部分构成:

    • 版本号:表示报文使用的 HTTP 协议版本,上图中版本为 HTTP/2;

    • 状态码:一个三位数,用代码的形式表示处理的结果,比如 200 是成功,404 是资源不存在;

    • 原因短语:作为数字状态码补充,是状态码的简短文字描述,例如“OK”“Not Found”。

    而后面的“Content-Type”、“Connection”等等都属于 header,报文的最后是一个空白行结束,没有 body。

    多数情况下 HTTP 报文只有 header 没有 body。虽然 HTTP 协议对 header 的大小没有做限制,但因为头部太大可能会占用大量的服务器资源,影响运行效率。因此各个 Web 服务器都不允许过大的请求头。即便如此很多时候互联网上依然是很多大头在跑来跑去。

    为了尽可能减少“大头”占用的资源,减少检测错误地址访问的时间,网站一般选择状态码来负担这个责任,因为数字比起文字能够更好地减小 HTTP 报文头部体积。

    响应报文可以让客户端快速地通过状态码知道请求是否被正确处理,让服务端可以通过状态码选择最恰当的状态处理请求回复客户端。同时通过各类状态码,让服务端明确告知客户端响应状态,让客户端明确自己的下一步操作。

    目前 RFC 标准里总共有 41 个状态码,并允许自行扩展。Apache、Nginx 等 Web 服务器都定义了一些专有的状态码。在开发 Web 应用的时候,我们也可以在不冲突前提下设置自己的专有状态码。

    常见状态码

    接下来,我们详说一下常见的各个状态码都代表着什么?

    状态码的意义在于表达 HTTP 数据处理的“状态”,客户端可以依据代码适时转换处理状态,一般是一个十进制数字,而 RFC 标准里规定的状态码是三位数,取值范围从 000 到 999。常见的状态码有一定的设计格式,被分成了五类,用数字的第一位表示分类,而 0~99 不用,这样状态码的实际可用范围就大大缩小了,由 000~999 变成了 100~599。

    1xx

    1×× 类状态码属于提示信息,是协议处理的中间状态,实际能够用到的时候很少。

    我们偶尔能够见到的是 “101 Switching Protocols”。它的意思是客户端使用 Upgrade 头字段,要求在 HTTP 协议的基础上改为其他的协议继续通信,比如 WebSocket。而如果服务器也同意变更协议,就会发送状态码 101,但这之后的数据传输就不会再使用 HTTP 了。

    此外还有 “100 Continue” 。表示目前为止一切正常, 客户端应该继续请求, 如果已完成请求则忽略。一般出现在文件上传中。

    2xx

    2×× 类状态码表示服务器收到并成功处理了客户端的请求,这也是客户端最愿意看到的状态码。

    “200 OK”是最常见的成功状态码,表示一切正常,服务器如客户端所期望的那样返回了处理结果。

    “204 No Content”是另一个很常见的成功状态码,它的含义与“200 OK”基本相同,但响应头后没有 body 数据。

    “206 Partial Content” 一般用于分块下载或断点续传的基础,在客户端发送“范围请求”、要求获取资源的部分数据时出现,它与 200 一样,也是服务器成功处理了请求,但 body 里的数据不是资源的全部,而是其中的一部分。状态码 206 通常还会伴随着头字段“Content-Range”,表示响应报文里 body 数据的具体范围,供客户端确认,例如“Content-Range: bytes 0-66/888”,意思是此次获取的是总计 888 个字节的前 66 个字节。

    又拍云 CDN 的分块获取响应 206

    3xx

    3×× 类状态码表示客户端请求的资源发生了变动,客户端必须用新的 URI 重新发送请求获取资源,也就是通常所说的“重定向”,包括“著名”的 301、302 跳转。

    “301 Moved Permanently”俗称“永久重定向”,含义是此次请求的资源已经不存在了,需要改用新的 URI 再次访问。与它类似的是“302 Found”,曾经的描述短语是“Moved Temporarily”,俗称“临时重定向”,意思是请求的资源还在,但需要暂时用另一个 URI 来访问。

    “304 Not Modified” 是一个比较有意思的状态码,它用于 If-Modified-Since 等条件请求,表示资源未修改,用于缓存控制。它不具有通常的跳转含义,但可以理解成“重定向已到缓存的文件”(即“缓存重定向”)。

    又拍云存储 304 缓存校验

    4xx

    4××类状态码表示客户端发送的请求报文有误,服务器无法处理,它是具有真正的“错误码”含义的状态码了。

    “400 Bad Request”是一个通用的错误码,表示请求报文有错误,但具体是数据格式错误、缺少请求头或者还是其他错误则不会明确指示,因此在 Web 开发时一般会尽量避免给客户端返回 400,使用其他更有明确含义的状态码。

    “403 Forbidden”实际上不是客户端的请求出错,而是表示服务器禁止访问资源。原因可能多种多样,例如信息敏感、法律禁止等。

    “404 Not Found”可能是我们最常看到的一个状态码,它一般指资源在本服务器上未找到,所以无法提供给客户端。

    4×× 里剩下的一些代码较明确地说明了错误的原因,都很好理解,开发中常用的有:

    • 405 Method Not Allowed:不允许使用某些方法操作资源,例如不允许 POST 只能 GET;

    • 406 Not Acceptable:资源无法满足客户端请求的条件,例如请求中文但只有英文;

    • 408 Request Timeout:请求超时,服务器等待了过长的时间;

    • 409 Conflict:多个请求发生了冲突,可以理解为多线程并发时的竞态;

    • 413 Request Entity Too Large:请求报文里的 body 太大;

    • 414 Request-URI Too Long:请求行里的 URI 太大;

    • 429 Too Many Requests:客户端发送了太多的请求,触发了服务器的限制;

    • 431 Request Header Fields Too Large:请求头某个字段或总体太大。

    5xx

    5×× 类状态码表示客户端请求报文正确,但服务器在处理时内部发生了错误,无法返回应有的响应数据,是服务器端的“错误码”。

    “500 Internal Server Error” 与 400 类似,也是一个通用的错误码,服务器究竟发生了什么错误我们是不知道的。不过和 400 的响应相反,开发人员通常不会把服务器内部的出错详细信息返回给访问端。虽然不利于调试,但能够防止黑客的窥探或者分析。

    “501 Not Implemented” 表示客户端请求的功能还不支持,类似于“即将开业,敬请期待”的意思。

    “502 Bad Gateway” 通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的。

    “503 Service Unavailable”表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503。

    如何处理 404

    回到我们开头所说的 404 问题。在实际业务中,难免会碰到输入了错误链接地址访问到不存在的资源,或者服务器突发故障无法访问的情况。但 Web 服务器默认提供的错误响应页面,无论 Nginx、Apache 或者是 IIS,都不是十分美观,页面简陋、呆板,且对用户不友好,无法给用户提供直观明了的信息,造成用户使用体验的下降。

    因此,很多开发者均使用自定义错误页面的方式,来增强户体验,避免用户流失。以 404 举例来说,自定义 404 页面通用的做法是在页面中放置网站快速导航链接、搜索框以及网站提供的特色服务,这样可以有效的帮助用户访问站点并获取需要的信息。

    腾讯公益 404 页面

    例如很多开发者会使用腾讯公益提供的“宝贝回家 - 公益 404 项目”,开发者可以在自定义的 404 界面中引用一段代码,当用户访问到 404 的资源,网页会显示访问资源不存在,同时加载一些失踪儿童的信息,通过互联网来迅速传播失踪儿童信息,从而提高找回失踪儿童的概率。这种操作让科技充满了温度,体现了人文关怀,正是科技的浪漫所在。

    如果你不知道如何自定义错误响应页,但是又很想拥有。你可以看一下又拍云的 CDN 、或者云存储服务的自定义页面功能。它可以帮助你快速的配置 4XX、5XX 的错误响应页。只需要打开控制台,就可以根据自己的需求配置错误响应也和错误响应图,非常方便好用。

    除此之外,还可以通过边缘规则,让不同错误码对应不同的网址跳转、URL 改写等网页引导操作。

  • 相关阅读:
    eslint 的 env 配置是干嘛使的?
    cookie httpOnly 打勾
    如何定制 antd 的样式(theme)
    剑指 Offer 66. 构建乘积数组
    剑指 Offer 65. 不用加减乘除做加法
    剑指 Offer 62. 圆圈中最后剩下的数字
    剑指 Offer 61. 扑克牌中的顺子
    剑指 Offer 59
    剑指 Offer 58
    剑指 Offer 58
  • 原文地址:https://www.cnblogs.com/upyun/p/14763392.html
Copyright © 2011-2022 走看看