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. ensp删除静态路由命令_eNSP配置静态路由
  2. 【VMCloud云平台】SCO(四)流程准备
  3. R语言使用ggplot2包geom_jitter()函数绘制分组(strip plot,一维散点图)带状图(双分类变量分组:色彩配置、添加箱图、位置参数调整)实战
  4. TypeScript 泛型
  5. Spring MVC中数据绑定流程和原理
  6. 数据增强_开源算法FMix:用于深度学习中增强混合样本数据增强
  7. subprocess 模块
  8. c语言求平衡因子,平衡二叉树(AVL树)的基本操作
  9. windows下virtualenv中安装MySQL-python
  10. 【纸牌识别】基于matlab形态学扑克牌识别【含Matlab源码 1352期】
  11. 会计计算机论文,关于计算机论文格式模板,关于电算化会计相关论文范文资料...
  12. C语言三种形式编九九乘法表,C语言九九乘法表(五种输出形式)
  13. et al和etc区别
  14. 一套牛逼哄哄的开源的监控系统(附源码)
  15. A Beginner‘s Guide To Understanding Convolutional Neural Networks(part 1)
  16. Kali安装天使之剑AngelSword,python3的poc!!
  17. 机器学习之逻辑回归(对数几率回归)
  18. PMCAFF | 小饭桌实战沙盘心得:积累不确定性中的确定性优势,一步步走向成功...
  19. 被调查7小时心生怨气 男子朋友圈辱骂警察被行拘
  20. I - 后缀数组二·重复旋律2 HihoCoder - 1407

热门文章

  1. 微信小程序实现客服默认自动回复功能
  2. 修复关于DxO Nik Collection 2.0.8在Photoshop 2020不能显示中文问题
  3. 在QQ浏览器打开html,QQ浏览器显示网页打开错误的处理
  4. oracle数据块坏,ORACLE中修复数据块损坏
  5. 纯CSS制作简单几何图形
  6. 时尚行业的二维码应用!2021 全新流行趋势
  7. Delta对冲:实际波动率 VS 隐含波动率
  8. 百度地图+vue+element搜索定位经纬度坐标
  9. RAdam和LookAhead合二为一
  10. JAVACC使用总结(四):LOOKAHEAD解决语法选择冲突的利刃