天马行空网站建设,网站上人家做的简历,wordpress先使用说明,重庆网站建设是什么参考来源#xff1a; 极客时间-透视HTTP协议(作者#xff1a;罗剑锋)#xff1b;
01-状态码分类 开头的 Version 部分是 HTTP 协议的版本号#xff0c;通常是HTTP/1.1#xff0c;用处不是很大。后面的 Reason 部分是原因短语#xff0c;是状态码的简短文字描述#xff…参考来源 极客时间-透视HTTP协议(作者罗剑锋)
01-状态码分类 开头的 Version 部分是 HTTP 协议的版本号通常是HTTP/1.1用处不是很大。后面的 Reason 部分是原因短语是状态码的简短文字描述例如“OK”“Not Found”等等也可以自定义。但它只是为了兼容早期的文本客户端而存在提供的信息很有限目前的大多数客户端都会忽略它。所以状态行里有用的就只剩下中间的状态码StatusCode了。它是一个十进制数字以代码的形式表示服务 器对请求的处理结果就像我们通常编写程序时函数返回的错误码一样。
不过你要注意它的名字是“状态码”而不是“错误码”。也就是说它的含义不仅是错误更重要的意义在于表达HTTP 数据处理的“状态”客户端可以依据代码适时转换处理状态例如继续发送请求、切换协议重定向跳转等有那么点 TCP 状态转换的意思。
RFC 标准把状态码分成了五类用数字的第一位表示分类而 0~99 不用这样状态码的实际可用范围就大大缩小了由 000~999 变成了 100~599。
这五类的具体含义是 1××提示信息表示目前是协议处理的中间状态还需要后续的操作 2××成功报文已经收到并被正确处理 3××重定向资源位置发生变动需要客户端重新发送请求 4××客户端错误请求报文有误服务器无法处理 5××服务器错误服务器在处理请求时内部发生了错误。
在 HTTP 协议中正确地理解并应用这些状态码不是客户端 或服务器单方的责任而是双方共同的责任。
状态码-1××
1××类状态码属于提示信息是协议处理的中间状态实际能够用到的时候很少。我们偶尔能够见到的是“101 Switching Protocols”。它的意思是客户端使用 Upgrade 头字段要求在 HTTP 协议的基础上改成其他的协议继续通信比如 WebSocket。而如果服务器也同意变更协议就会发送状态码 101但这之后的数据传输就不会再使用 HTTP 了。
状态码-2××
2××类状态码表示服务器收到并成功处理了客户端的请求这也是客户端最愿意看到的状态码。 “200 OK”是最常见的成功状态码表示一切正常服务器如客户端所期望的那样返回了处理结果如果是非 HEAD请求通常在响应头后都会有 body 数据。“204 No Content”是另一个很常见的成功状态码它的含义与“200 OK”基本相同但响应头后没有 body 数据。所以对于 Web 服务器来说正确地区分 200 和 204是很必要的。
“206 Partial Content”是 HTTP 分块下载或断点续传的基础在客户端发送“范围请求”、要求获取资源的部分数据时出现它与 200 一样也是服务器成功处理了请求但 body 里的数据不是资源的全部而是其中的一部分。状态码 206 通常还会伴随着头字段“Content-Range”表示响应报文里 body 数据的具体范围供客户端确认例如“Content-Range: bytes 0-99/2000”意思是此次获取的是总计 2000 个字节的前 100 个字节。
状态码-3xx,301,302,304
3××类状态码表示客户端请求的资源发生了变动客户端必 须用新的 URI 重新发送请求获取资源也就是通常所说 的“重定向”包括著名的 301、302 跳转。
“301 Moved Permanently”俗称“永久重定向”含义是此次请求的资源已经不存在了需要改用改用新的 URI再次访问。与它类似的是“302 Found”曾经的描述短语是“Moved Temporarily”俗称“临时重定向”意思是请求的资源还在但需要暂时用另一个 URI 来访问。
301 和 302 都会在响应头里使用字段Location指明后续要跳转的 URI最终的效果很相似浏览器都会重定向到新的URI。两者的根本区别在于语义一个是“永久”一个是“临时”所以在场景、用法上差距很大。
比如你的网站升级到了 HTTPS原来的 HTTP 不打算用了这就是“永久”的所以要配置 301 跳转把所有的HTTP 流量都切换到 HTTPS。
再比如今天夜里网站后台要系统维护服务暂时不可用这就属于“临时”的可以配置成 302 跳转把流量临时切换到一个静态通知页面浏览器看到这个 302 就知道这只是暂时的情况不会做缓存优化第二天还会访问原来的地址。
“304 Not Modified” 是一个比较有意思的状态码它用于 If-Modified-Since 等条件请求表示资源未修改用于缓存控制。它不具有通常的跳转含义但可以理解成“重定向已到缓存的文件”即“缓存重定向”。
301、302 和 304 分别涉及了 HTTP 协议里重要的“重定向跳转”和“缓存控制”
4××类状态码表示客户端发送的请求报文有误服务器无法 处理它就是真正的“错误码”含义了。
“400 Bad Request”是一个通用的错误码表示请求报文有错误但具体是数据格式错误、缺少请求头还是 URI 超长它没有明确说只是一个笼统的错误客户端看到 400只会是“一头雾水”“不知所措”。所以在开发 Web 应用时应当尽量避免给客户端返回 400而是要用其他更有明确含义的状态码。
“403 Forbidden”实际上不是客户端的请求出错而是表示服务器禁止访问资源。原因可能多种多样例如信息敏感、法律禁止等如果服务器友好一点可以在 body 里详细说明拒绝请求的原因不过现实中通常都是直接给一个“闭门羹”。
“404 Not Found”可能是我们最常看见也是最不愿意看到的一个状态码它的原意是资源在本服务器上未找到所以无法提供给客户端。但现在已经被“用滥了”只要服务器“不高兴”就可以给出个 404而我们也无从得知后面到底是真的未找到还是有什么别的原因某种程度上它比403 还要令人讨厌。
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请求头某个字段或总体太大
5××类状态码表示客户端请求报文正确但服务器在处理时内部发生了错误无法返回应有的响应数据是服务器端的“错误码”。
“500 Internal Server Error”与 400 类似也是一个通用的错误码服务器究竟发生了什么错误我们是不知道的。不过对于服务器来说这应该算是好事通常不应该把服务器内部的详细信息例如出错的函数调用栈告诉外界。虽然不利于调试但能够防止黑客的窥探或者分析。
“501 Not Implemented”表示客户端请求的功能还不支持这个错误码比 500 要“温和”一些和“即将开业敬请期待”的意思差不多不过具体什么时候“开业”就不好说了。
“502 Bad Gateway”通常是服务器作为网关或者代理时返回的错误码表示服务器自身工作正常访问后端服务器时发生了错误但具体的错误原因也是不知道的。
“503 Service Unavailable”表示服务器当前很忙暂时无法响应服务我们上网时有时候遇到的“网络服务正忙请稍后重试”的提示信息就是状态码 503。
503 是一个“临时”的状态很可能过几秒钟后服务器就不那么忙了可以继续提供服务所以 503 响应报文里通常还会有一个“Retry-After”字段指示客户端可以在多久以后再次尝试发送请求。
02-http特点
首先 HTTP 协议是一个“灵活可扩展”的传输协议。 第二个特点 HTTP 协议是一个“可靠”的传输协议。 第三个特点HTTP 协议是一个应用层的协议 第四个特点HTTP 协议使用的是请求 - 应答通信模式 第五个特点HTTP 协议是无状态的。
其他特点 除了以上的五大特点其实 HTTP 协议还可以列出非常多的特点例如传输的实体数据可 缓存可压缩、可分段获取数据、支持身份认证、支持国际化语言等。但这些并不能算是 HTTP 的基本特点因为这都是由第一个“灵活可扩展”的特点所衍生出来的。
03-http性能
用六个字来概括“不算差不够好”. HTTP 协议基于 TCP/IP并且使用了**“请求 - 应答”的通信模式**所以性能的关键就在这两点上。 必须要说的是TCP 的性能是不差的否则也不会纵横互联网江湖四十余载了而且它已 经被研究的很透集成在操作系统内核里经过了细致的优化足以应付大多数的场景。
04-提高传输大文件效率的两个方法压缩和分块传输
压缩数据-Encoding type但仅有 MIME type 还不够因为 HTTP 在传输时为了节约带宽有时候还会压缩数据为了不要让浏览器继续“猜”还需要有一个“Encoding type”告诉数据是用的什么编码格式这样对方才能正确解压缩还原出原始的数据。
比起 MIME type 来说Encoding type 就少了很多常用 的只有下面三种
gzipGNU zip 压缩格式也是互联网上最流行的压缩格式deflatezlibdeflate压缩格式流行程度仅次于gzipbr一种专门为 HTTP 优化的新压缩算法Brotli。HTTP 协议为此定义了两个 Accept 请求头字段和两个Content 实体头字段用于客户端和服务器进行“内容协商”。也就是说客户端用 Accept 告诉服务器希望接收什么样的数据而服务器用 Content 头告诉客户端实际发送了什么样的数据。
Accept字段标记的是客户端可理解的 MIME type可以用“,”做分隔符列出多个类型让服务器有更多的选择余地例如下面的这个头 这就是告诉服务器“我能够看懂 HTML、XML 的文本还有 webp 和 png 的图片请给我这四类格式的数据”。
相应的服务器会在响应报文里用头字段Content-Type告诉实体数据的真实类型
Accept-Encoding字段标记的是客户端支持的压缩格式例如上面说的 gzip、deflate 等同样也可以用“,”列出多个服务器可以选择其中一种来压缩数据实际使用的压缩格式放在响应头字段Content-Encoding里。
不过这两个字段是可以省略的如果请求报文里没有Accept-Encoding 字段就表示客户端不支持压缩数据 如果响应报文里没有 Content-Encoding 字段就表示响应数据没有被压缩。
压缩是把大文件整体变小我们可以反过来思考如果大文件整体不能变小那就把它“拆开”分解成多个小块把这些小块分批发给浏览器浏览器收到后再组装复原。 这样浏览器和服务器都不用在内存里保存文件的全部每次只收发一小部分网络也不会被大文件长时间占用内存、带宽等资源也就节省下来了。
这种“化整为零”的思路在 HTTP 协议里就是“chunked”分块传输编码在响应报文里用头字 段“Transfer-Encoding: chunked”来表示意思是报文里的 body 部分不是一次性发过来的而是分成了许多的块chunk逐个发送。
分块传输也可以用于“流式数据”例如由数据库动态生成的表单页面这种情况下 body 数据的长度是未知的无法在头字段“Content-Length”里给出确切的长度所以也只能用 chunked 方式分块发送。
“Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的也就是说响应报文里这两 个字段不能同时出现一个响应报文的传输要么是长度已知要么是长度未知chunked这一点你一定要记住。
分块传输的编码规则
每个分块包含两个部分长度头和数据块长度头是以 CRLF回车换行即\r\n结尾的一行明文用 16 进制数字表示长度数据块紧跟在长度头后最后也用 CRLF 结尾但数据不包含 CRLF最后用一个长度为 0 的块表示结束即“0\r\n\r\n”
05-范围请求-非必备功能
比如你在看当下正热播的某穿越剧想跳过片头直接看正片或者有段剧情很无聊想拖动进度条快进几分钟这实际上是想获取一个大文件其中的片段数据而分块传输并 没有这个能力。HTTP 协议为了满足这样的需求提出了“范围请求”range requests的概念允许客户端在请求头里使用专用字段来表示只获取文件的一部分相当于是客户端的“化整为零”。
范围请求不是 Web 服务器必备的功能可以实现也可以不实现所以服务器必须在响应头里使用字段“Accept-Ranges: bytes”明确告知客户端“我是支持范围请求的”。
如果不支持的话该怎么办呢服务器可以发送“Accept-Ranges: none”或者干脆不发送“Accept-Ranges”字段这样客户端就认为服务器没有实现范围请求功能只能老老实实地收发整块文件了。
请求头Range是 HTTP 范围请求的专用字段格式是“bytesx-y”其中的 x 和 y 是以字节为单位的数据范围。
要注意 x、y 表示的是“偏移量”范围必须从 0 计数例如前 10 个字节表示为“0-9”第二个 10 字节表示为“10-19”而“0-10”实际上是前 11 个字节。
Range 的格式也很灵活起点 x 和终点 y 可以省略能够很方便地表示正数或者倒数的范围。假设文件是 100 个字节那么
“0-”表示从文档起点到文档终点相当于“0-99”即整个文件 “10-”是从第 10 个字节开始到文档末尾相当于“10-99” “-1”是文档的最后一个字节相当于“99-99” “-10”是从文档末尾倒数 10 个字节相当于“90-99”。
服务器收到 Range 字段后需要做四件事
第一它必须检查范围是否合法比如文件只有 100 个字节但请求“200-300”这就是范围越界了。服务器就会返回状态码416意思是“你的范围请求有误我无法处理请再检查一下”。
第二如果范围正确服务器就可以根据 Range 头计算偏移量读取文件的片段了返回状态码“206 PartialContent”和 200 的意思差不多但表示 body 只是原数据的一部分。
第三服务器要添加一个响应头字段Content-Range告诉片段的实际偏移量和资源的总大小格式是“bytes x-y/length”与 Range 头区别在没有“”范围后多了 总长度。例如对于“0-10”的范围请求值就是“bytes0-10/100”。
最后剩下的就是发送数据了直接把片段用 TCP 发给客户端一个范围请求就算是处理完了。