HTTP头部实体

HTTP协议报文是按照header+body的形式,其中body传输的时候是二进制文件,但具体按照什么格式来读取,必须有所约定。就像一个文件,我们改变不同的后缀名,打开完全是不一样的。

报文格式借鉴了电子邮件系统的MIME,“多用途互联网邮件扩展”(Multipurpose Internet Mail Extensions)。

常见的分为下列几种:

text,文本格式的可读数据,比如text/html,text/plain,text/css;

image,图像数据,image/gif,image/jpeg;

audio/video,音视频数据,audio/mpeg,video/mp4;

application,数据格式不固定,可以是文本也可以是二进制数据。application/json,application/javascript,application/pdf。

还有一个编码方式encoding type,选择body体的压缩方式:

gzip:GNU zip 压缩格式,也是互联网上最流行的压缩格式;

deflate:zlib(deflate)压缩格式,流行程度仅次于 gzip;

br:一种专门为 HTTP 优化的新压缩算法(Brotli)。

这样,客户端用Accept,Accept-Encoding来说明可以接受的内容和编码方式;服务端用Content-Type,Content-Encoding来解释最终选择发送的格式和编码方式。

如果请求报文里没有 Accept-Encoding 字段,就表示客户端不支持压缩数据;如果响应报文里没有 Content-Encoding 字段,就表示响应数据没有被压缩。

我们书写的代码都是用英文书写,但客户端那边的使用者可能是各个国家,所以存在一个语言问题。Accept-language就是记录这个。与语言对应的是不同语言的字符集charset。

现在的浏览器都支持多种字符集,通常不会发送 Accept-Charset,而服务器也不会发送 Content-Language。在请求头里一般只会有 Accept-Language 字段,响应头里只会有 Content-Type 字段。对应我自己实验的现象,客户端只是提出请求语言,然后客户端回复UTF-8统一编码即可,然后再交给客户端来自行转换成需求语言。

响应头里没有对应的 Content-Charset,而是在Content-Type字段的数据类型后面用“charset=xxx”来表示。

在 HTTP 协议里用 Accept、Accept-Encoding、Accept-Language 等请求头字段进行内容协商的时候,还可以用一种特殊的“q”参数表示权重来设定优先级,这里的“q”是“quality factor”的意思。

权重的最大值是 1,最小值是 0.01,默认值是 1,如果值是 0 就表示拒绝。具体的形式是在数据类型或语言代码后面加一个“;”,然后是“q=value”。

这样给服务器一些可回复的选择,对应服务器对于内容协商的过程是不透明的,每个 Web 服务器使用的算法都不一样。最后会给出一个Vary参数,记录服务器在内容协商时参考的请求头字段。

HTTP协议并不属于强制性的要求,所以其实客户端发过去的头文件描述的请求,返回报文并不一定按要求返回。比如我自己实验的几个网站,发现请求的Accept-Language是zh,但返回的Content-Type是***,charset=UTF-8。我理解等于无论要求的是什么语言,服务器统一用UTF-8回复,这样再由服务器来进行处理。

如何在有限带宽下高效传输大文件,将大文件直接传输会把网络带宽完全抢占,这也是我们以前经常说起的,下载抢网速的原因。

数据压缩,与之前请求头的Accept-Encoding有关,但此类压缩一般都是对文本类的压缩有效,像音视频这类原本就已经压缩的文件,再次压缩的效果并不好。

除了数据压缩外,另一个思路就是人为的将大文件进行切割,变成一系列的小文件后再来传输,这样更小的层面来说就是传输小文件了,再浏览器这端再把数据包组合成大文件,叫做分块传输,chunked(HTTP/2.0已经不支持)。对应响应报文里用头字段“Transfer-Encoding: chunked”来表示,意思是报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。

“Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的,也就是说响应报文里这两个字段不能同时出现,一个响应报文的传输要么是长度已知,要么是长度未知(chunked)。

分块传输的规格如下:

  1. 每个分块包含两个部分,长度头和数据块;
  2. 长度头是以 CRLF(回车换行,即\r\n)结尾的一行明文,用 16 进制数字表示长度;
  3. 数据块紧跟在长度头后,最后也用 CRLF 结尾,但数据不包含 CRLF;
  4. 最后用一个长度为 0 的块表示结束,即“0\r\n\r\n”。

分块传输并不是分为多个HTTP响应报文,而是类似“长连接”的效果,body部分的报文是分块发送。

范围请求,是类似我们看视频跳过片头,只截取文件的部分进行传输。

范围请求不是 Web 服务器必备的功能,可以实现也可以不实现,如果支持该功能,服务器必须在响应头里使用字段“Accept-Ranges: bytes”明确告知。而如果不支持,则发送“Accept-Ranges: none”,或者干脆不发送“Accept-Ranges”字段。

请求头Range是 HTTP 范围请求的专用字段,格式是“bytes=x-y”,其中的 x 和 y 是以字节为单位的数据范围。要注意 x、y 表示的是“偏移量”,从 0 计数。这里的数据范围是指原数据的,如果是压缩文件,客户端没有办法掌握压缩后的数据范围和目标数据范围之间的偏差。

假设文件是 100 个字节,那么:

“0-”表示从文档起点到文档终点,相当于“0-99”,即整个文件;

“10-”是从第 10 个字节开始到文档末尾,相当于“10-99”;

“-1”是文档的最后一个字节,相当于“99-99”;

“-10”是从文档末尾倒数 10 个字节,相当于“90-99”。

服务器收到 Range 字段后,需要做四件事。

第一,它必须检查范围是否合法。类似数组索引,不能超出界限;

第二,如果范围正确,服务器就可以根据 Range 头计算偏移量,读取文件的片段了,返回状态码“206 Partial Content”表示 body 只是原数据的一部分;

第三,服务器响应包含头字段Content-Range,告诉片段的实际偏移量和资源的总大小,格式是“bytes x-y/length”;

第四,直接把片段用 TCP 发给客户端,一个范围请求就算是处理完了。

可以通过该方式实现多段下载,每段用不同的线程来执行。

范围请求甚至可以在一个HTTP请求中申请多段数据,在Range中用“,”分开,对应的响应报文Content-Type设置类型:“multipart/byteranges”再加上参数“boundary=xxx”给出段之间的分隔标记。

每个分段要用‘--’+分隔标记+CRLF开头,然后加上两个响应头Content-Type(不同与整个报文的Content-Type,是真实的具体类型)和Content-Range。多段数据结束的地方还需要用‘--’+分隔标记+‘--’+CRLF来标示。

透视HTTP协议-进阶篇-极客时间-学习笔记相关推荐

  1. 极客时间学习笔记-左耳听风

    本文笔记全部来自<极客时间-左耳听风> 2018-09-21 弹力设计篇之"幂等性设计" Twitter 的 Snowflake 就是一个比较好用的全局 ID实现. P ...

  2. 《零基础学Python》——极客时间——学习笔记

    第二章 Python基础语法 Python程序的书写规则 基础数据类型 类型判断 type() 强制类型转换 目标类型(要转换的数据) 变量的定义和常用操作 习题 题目: 练习一 变量的定义和使用 定 ...

  3. 极客时间学习笔记:03芯片分类

    芯片与集成电路的区别? 芯片肯定不全是集成电路.芯片里面,大约只有 80% 属于集成电路,其余的都是光电器件.传感器和分立器件,行业内把这些器件称为 O-S-D(Optoelectronic, Sen ...

  4. 极客时间学习笔记☞《苏杰的产品创新课》(二)

    竞品生态: 用不同方案解决相似问题的产品,往往会成为行业里颠覆巨头的下一代产品.竞品不是你死我活,也可以是互相成就. 明确竞争对手,找寻真正值得分析的竞争对手. 点子过滤器: 过滤掉不靠谱的点子,做值 ...

  5. 极客时间学习笔记☞《苏杰的产品创新课》(一)

    项目经理与产品经理的差异: 目标的差异:项目经理更强调执行,是接到一个任务,正确地做事,产品经理更强调创新,是设定一个目标,做正确的事.这两种能力很难兼备,甚至有些互相冲突. 产品经理后续发展趋势: ...

  6. 极客时间学习笔记☞《苏杰的产品创新课》(三)

    产品的生命中心: 想清楚.做出来.推出去.产品生命周期分为四个典型阶段,分别叫做:验证期.爆发期.平台期.衰退期. 围绕既定的核心用户,把重要的需求场景满足得越来越好.拥有"回头客" ...

  7. MySQL进阶篇--超赞详尽学习笔记(好评如潮)

    目录 一.MySQL体系结构 二.存储引擎 2.1 存储引擎简介 2.2 存储引擎特点 2.3 存储引擎选择 三.索引 3.1 索引概述 3.2 索引结构 3.2.1 B-Tree 3.2.2 B+T ...

  8. 极客时间课程笔记:业务安全

    业务安全 业务安全体系:对比基础安全,业务安全有哪些不同? 业务安全和基础安全在本质上就有很大的不同:在基础安全中,黑客将技术作为核心竞争力:在业务安全中,黑产将资源作为核心竞争力.谁能够以更低的成本 ...

  9. 极客时间 Redis核心技术与实战 笔记(基础篇)

    Redis 概览 Redis 知识全景图 Redis 问题画像图 基础篇 基本架构 数据结构 数据类型和底层数据结构映射关系 全局哈希表 链式哈希解决哈希冲突 渐进式 rehash 不同数据结构查找操 ...

  10. 硅谷python_来自硅谷的Python最佳实践指南 | 极客时间

    这几年,学 Python 的程序员的确越来越多了,甚至不少人把 Python 当作第一语言来学习.也难怪,Python 的优点太多了,它语言简洁.开发效率高.可移植性强,并且可以和其他编程语言(比如 ...

最新文章

  1. JedisConnectionException: java.net.SocketException: Broken pipe
  2. python turtle基本语法_Python 基础语法-turtle篇
  3. Android permission 访问权限一览
  4. 如何借助Kubernetes实现持续的业务敏捷性
  5. 企业大数据的主要竞争优势
  6. 友盟分享没有链接的问题
  7. live2dmesh渲染优先级_Live2D 性能优化
  8. 顺着IP地址他们能找到我家吗?
  9. 计算机考研复试之计算机网络
  10. word中的符号无法添加(窗口变成灰色)
  11. python爬虫:xpath解析
  12. mysql正则时间格式_用正则表达式校验时间格式的正确性
  13. 5.3 Hessenberg法求特征值
  14. 即食水产消费品公司“不等食品”获千万元级A轮融资,险峰长青领投...
  15. Redisson封装及应用实例
  16. C#获取企业微信打卡数据
  17. 基于jaccard计算论文对的reference相似度的算法(2)
  18. Beta函数和Gamma函数的关系
  19. 2021年材料员-通用基础(材料员)考试试题及材料员-通用基础(材料员)作业模拟考试
  20. 利用Biopython 快速根据pmid 来下载参考文献信息

热门文章

  1. python保存超大数据excel表格——大于65532
  2. 字段名的映射的三种方式
  3. flutter type ‘Null‘ is not a subtype of type ‘String‘
  4. 第七周 项目2 - 建立链队算法库
  5. JavaScript入门案例
  6. 颜色的RGBnbsp;指数
  7. htmla标签下划线去除_div css网页开发布局时a标签去掉下划线
  8. key去掉下划线自动大写首字母工具类
  9. Python实现毫秒级抢单,6翻了!
  10. 前端页面闪动(vue+ele 表格分页)