透视HTTP协议
罗剑锋(Chrono)
奇虎360技术专家,Nginx/OpenResty开源项目贡献者
立即订阅
6077 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词|To Be a HTTP Hero
免费
破冰篇 (7讲)
01 | 时势与英雄:HTTP的前世今生
02 | HTTP是什么?HTTP又不是什么?
03 | HTTP世界全览(上):与HTTP相关的各种概念
04 | HTTP世界全览(下):与HTTP相关的各种协议
05 | 常说的“四层”和“七层”到底是什么?“五层”“六层”哪去了?
06 | 域名里有哪些门道?
07 | 自己动手,搭建HTTP实验环境
基础篇 (7讲)
08 | 键入网址再按下回车,后面究竟发生了什么?
09 | HTTP报文是什么样子的?
10 | 应该如何理解请求方法?
11 | 你能写出正确的网址吗?
12 | 响应状态码该怎么用?
13 | HTTP有哪些特点?
14 | HTTP有哪些优点?又有哪些缺点?
进阶篇 (8讲)
15 | 海纳百川:HTTP的实体数据
16 | 把大象装进冰箱:HTTP传输大文件的方法
17 | 排队也要讲效率:HTTP的连接管理
18 | 四通八达:HTTP的重定向和跳转
19 | 让我知道你是谁:HTTP的Cookie机制
20 | 生鲜速递:HTTP的缓存控制
21 | 良心中间商:HTTP的代理服务
22 | 冷链周转:HTTP的缓存代理
安全篇 (7讲)
23 | HTTPS是什么?SSL/TLS又是什么?
24 | 固若金汤的根本(上):对称加密与非对称加密
25 | 固若金汤的根本(下):数字签名与证书
26 | 信任始于握手:TLS1.2连接过程解析
27 | 更好更快的握手:TLS1.3特性解析
28 | 连接太慢该怎么办:HTTPS的优化
29 | 我应该迁移到HTTPS吗?
飞翔篇 (4讲)
30 | 时代之风(上):HTTP/2特性概览
31 | 时代之风(下):HTTP/2内核剖析
32 | 未来之路:HTTP/3展望
33 | 我应该迁移到HTTP/2吗?
探索篇 (5讲)
34 | Nginx:高性能的Web服务器
35 | OpenResty:更灵活的Web服务器
36 | WAF:保护我们的网络服务
37 | CDN:加速我们的网络服务
38 | WebSocket:沙盒里的TCP
总结篇 (2讲)
39 | HTTP性能优化面面观(上)
40 | HTTP性能优化面面观(下)
答疑篇 (2讲)
41 | Linux/Mac实验环境搭建与URI查询参数
42 | DHE/ECDHE算法的原理
结束语 (1讲)
结束语 | 做兴趣使然的Hero
透视HTTP协议
登录|注册

15 | 海纳百川:HTTP的实体数据

Chrono 2019-07-01
你好,我是 Chrono。
今天我要与你分享的话题是“海纳百川:HTTP 的实体数据”。
这一讲是“进阶篇”的第一讲,从今天开始,我会用连续的 8 讲的篇幅来详细解析 HTTP 协议里的各种头字段,包括定义、功能、使用方式、注意事项等等。学完了这些课程,你就可以完全掌握 HTTP 协议。
在前面的“基础篇”里我们了解了 HTTP 报文的结构,知道一个 HTTP 报文是由“header+body”组成的。但那时我们主要研究的是 header,没有涉及到 body。所以,“进阶篇”的第一讲就从 HTTP 的 body 谈起。

数据类型与编码

在 TCP/IP 协议栈里,传输数据基本上都是“header+body”的格式。但 TCP、UDP 因为是传输层的协议,它们不会关心 body 数据是什么,只要把数据发送到对方就算是完成了任务。
而 HTTP 协议则不同,它是应用层的协议,数据到达之后工作只能说是完成了一半,还必须要告诉上层应用这是什么数据才行,否则上层应用就会“不知所措”。
你可以设想一下,假如 HTTP 没有告知数据类型的功能,服务器把“一大坨”数据发给了浏览器,浏览器看到的是一个“黑盒子”,这时候该怎么办呢?
当然,它可以“猜”。因为很多数据都是有固定格式的,所以通过检查数据的前几个字节也许就能知道这是个 GIF 图片、或者是个 MP3 音乐文件,但这种方式无疑十分低效,而且有很大几率会检查不出来文件类型。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《透视HTTP协议》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(37)

  • 彧豪
    上周五和服务端做上传图片的时候遇到过这个content-type的问题,上传图片时候我这边需要设置content-type:"image/jpg",然后传完了,我在预览的时候获取图片的地址,此时比如通过a标签的方式打开新标签预览该图片时才能成功预览,不然如果使用上传的js-sdk设置的默认类型:content-type:"octet-stream",那么浏览器就不认识这个图片了,转而会下载这个文件(图片),所以我是不是可以理解为content-type这字段在请求头,和响应头里都能使用?或者上传文件这个业务又不同于一般的请求操作呢?

    作者回复: 是的,看来是我没说清楚,导致有的同学误会了。

    content-type是实体字段,所以请求和响应里都可以用,作用是指明body数据的类型。

    正文里为了叙述方便,只在服务器的响应报文里出现了content-type,实际上它是个通用字段,如果要发post请求,就需要带上它。

    2019-07-01
    19
  • 苦行僧
    现在很多小文件 比如图片 都往云存上放了 千万指定正确content-type 一旦指定错 批量修改太麻烦 而且会影响终端的解析

    作者回复: 经验之谈!

    2019-07-02
    10
  • BellenHsin
    这篇写的不错

    作者回复: thanks。

    2019-07-01
    8
  • 亚洲舞王.尼古拉斯赵四
    1.含义是:我这个请求最希望服务器给我返回的编码方式是gzip和deflate,他们俩在我这是最优的地位,我不接受br的编码方式,如果还有其他的编码方式的话对我来说权重0.5。服务器可能的响应头是
    HTTP/1.1 200 OK
    Content-Encoding: gzip

    2.请求头可能是
    POST /serv/v1/user/auth HTTP/1.1
    Content-Type: application/json
    Accept-Language: zh-CN, zh
    Accept-Charset: gbk, utf-8
    3.MIME类比快递的话就是你要快递的物品(衣服,食物等),Encoding就是快递你这个物品的包装方式,如果是衣服可能就随意一点一个袋子,如果是食物担心腐烂给你放个冰袋进去
    不知道回答的对不对,请老师指正

    作者回复: 回答的不错。

    第二个问题要修改一下,这也怪我没有说清楚。

    content-*字段也可以用在请求报文里,说明请求体的数据类型。在这里不能用accept字段,因为是post,所以要用content-language来指明body的语言类型,在content-type里用charset指明编码类型。

    可以参考其他同学的回答。

    2019-07-01
    7
  • -W.LI-
    老师好!那accept是不是有两个语意
    1.客户端希望接受(支持)的数据类型
    2.我发送的数据就是这个类型的。请用这些方式解析?
    问题:accept指定text。实际传的数据是一个json这样的后台会用text解析。然后拿不到数据是么?在请求头里加content -type这些字段会起作用么?

    作者回复: 1.accept是你说的第一个意思,没有第二个意思。

    2.第二个意思应该用Content-Type

    3.看后台逻辑如何处理,数据是肯定可以拿到的,而且json也属于text。

    4.在请求头里可以加content-type字段,表示请求体的数据类型。

    2019-07-01
    4
  • -W.LI-
    老师好!有个问题,之前遇到过一个发送ajax请求。前端忘记在content-type里面指定,application/json。后端接受数据失败。具体表现不太记得了好像都是null。后来前端加了content-type就好了。accept比较好理解就是发起请求放想要接受的内容。content-type是服务器,是响应类型的话。客户端在发送请求时压根就不知道啊,也不应该由客户端来设置。
    所以我想问的是,accept相关的都是请求头里面的数据
    content-type相关的都是响应头里的数据么?
    至于我前面正确的写法应该是在accept里面设置json类型。错写了content-type。框架做了兼容处理(在服务端看起来content-type起作用了)?
    谢谢老师

    作者回复: 客户端在发送请求的时候也有义务设置content-type,也应该是知道数据是什么类型的,你设置成json,服务器看到了就好处理。

    content-type是实体字段,请求响应里都可以出现。

    accept是告诉服务器,客户端支持什么类型,防止服务器发过来的数据不认识。

    2019-07-01
    4
  • MJ
    老师,每一个并发连接,都需要新建tcp三次握手吗?还是一次tcp握手后,可以并发多个连接?

    作者回复: 每建立一个连接就需要tcp握手,对同一个ip地址+端口,浏览器通常最多建立6个并发连接。

    2019-07-05
    3
  • 1900
    “所以后来就出现了 Unicode 和 UTF-8,把世界上所有的语言都容纳在一种编码方案里,UTF-8 也成为了互联网上的标准字符集。”

    这句话最后有点问题吧?Unicode才是字符集,应该是“遵循UTF-8字符编码方式的Unicode字符集也成为了互联网上的标准字符集”,是么?

    作者回复: 嗯,我说的时候不太准确。utf-8只是编码方案,Unicode是字符集。

    2019-07-01
    3
  • 走马
    accept 表达的是你想要的
    而你发送 post请求时,你发送的数据是给服务器的,这时候就需要像 服务器会用 content-type 标明它给你的数据类型一样,你也需要用 content- 来表明你给别人的数据的一些属性

    作者回复: √

    2019-07-04
    2
  • 啦啦啦
    不错不错,靠谱这篇,天天看这些参数一直不知道具体意思,今天老师讲了以后理解了

    作者回复: 继续努力。

    2019-07-02
    2
  • Geek_54edc1
    1.服务器优先按照gzip和deflate压缩,否则用其他压缩算法,但是不用brotli算法

    作者回复: √

    2019-07-01
    2
  • 隰有荷
    用post方法请求接口时,在客户端语言的设置上不能使用Accept-Language吗?为什么一定是Contenr-Language呢?是不是Accept-Language只用于get方式时,表明客户端需要的的语言呢?

    作者回复: post和get时都可以使用Accept-Language,表示客户端可以理解的语言,要求服务器按照指示返回数据。

    Content-Language表示的是body数据的语言,因为post带有body,所以要用Content-Language来告诉服务器,报文的body是什么。

    如果get报文也有body,那么它也可以使用Content-Language。

    Accept-Language是请求头字段,只要是发请求就可以带。

    Content-Language是实体头字段,只要是有body就可以带。

    2019-10-02
    1
  • 啦啦啦
    二刷

    作者回复: 努力学习!

    2019-07-10
    1
  • aNught
    老师,您好,如果我accep-encoding填写了gzip,那服务端发来的报文是是gzip压缩过的吗,我需要解压才行是吗?

    作者回复: accep-encoding:gzip表示客户端支持gzip,但服务器发过来的是否经过压缩需要看content-encoding,也有可能不压缩。

    2019-07-09
    1
  • 响雨
    Content-type: application/json; charset=utf-8
    Accept-language: zh-CN
    python中的requests模块发送url请求,post时一定要在header中加上Content-type,不然会报错。
    老师,我在mime中放了1G的MP4视频,为什么只有声音没有画面啊。

    作者回复: 应该用content-language,post时应该用content*字段描述body的语言。

    2019-07-04
    1
    1
  • 聂成阳
    老师,我访问极客时间https://account.geekbang.org/dashboard/user它的请求头是这样的:
    POST /account/user HTTP/1.1
    Host: account.geekbang.org
    Connection: keep-alive
    Content-Length: 2
    Accept: application/json, text/plain, */*
    Origin: https://account.geekbang.org
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    Content-Type: application/json
    Referer: https://account.geekbang.org/dashboard/buy
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    为啥post也使用accept-*呢?

    作者回复: 发post请求,服务器也会有响应报文,所以就需要用accept头告诉服务器,客户端能够接受什么样的数据。

    否则服务器发过来一个pb或者msgpack,你就没法处理了。

    2019-07-03
    1
  • 啦啦啦
    今天凌晨买的课程,然后现在一口气看完了

    作者回复: 学习也要劳逸结合,有张有弛。

    2019-07-02
    1
  • 风翱
    1、gzip的权重为1,deflate权重为1,其他的为0.5,br拒绝。
    2、
    Accept:appliction/json
    Accept-Encoding:gzip,deflate
    Accept-Language:zh-CN,zh;q=0.8
    3、MIME类比快递中的物品类型,如:酒类、生鲜类、药品类等,Encoding类比现付、货到付款(好像不是很贴切)

    作者回复: 1对。

    2需要使用content-*字段,不能用accept字段,可参考其他同学的回答。

    3的比喻还差一点,换成外包装比较合适。

    2019-07-02
    1
  • 苦行僧
    content-type 千万不能填错 否则其他终端解析会存在问题

    作者回复: 好经验多分享。

    2019-07-02
    1
  • Geek_54edc1
    content-type: application/json; charset=gbk 如果有压缩用content-encoding指定下,使用的语言可以通过charset判断出来

    作者回复: 对,不过最好还是加上content-language。

    2019-07-01
    1
    1
收起评论
37
返回
顶部