http协议

未匹配的标注

Http协议

Request Header

Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,und;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Content-Length: 143

Response Header

Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Server: BWS/1.1
Set-Cookie: BDSVRTM=390; path=/
Transfer-Encoding: chunked
X-Ua-Compatible: IE=Edge,chrome=1

Body的格式-MIME type

MIME 把数据分成了八大类,每个大类下再细分出多个子 类,形式是“type/subtype”的字符串

这里简单列举一下在 HTTP 里经常遇到的几个类别:

  1. text:即文本格式的可读数据,我们最熟悉的应该就是 text/html 了,表示超文本文档,此外还有纯文本 text/plain、样式表 text/css 等。
  2. image:即图像文件,有 image/gif、image/jpeg、 image/png 等。
  3. audio/video:音频和视频数据,例如 audio/mpeg、 video/mp4 等。
  4. application:数据格式不固定,可能是文本也可能是二 进制,必须由上层应用程序来解释。常见的有 application/json,application/javascript、 application/pdf ,application/x-www-form-urlencoded等,另外,如果实在是不知道数据是什 么类型,像刚才说的“黑盒”,就会是 application/octet-stream,即不透明的二进制数据

比如我们浏览器post提交表单经常遇到的

Content-Type:application/x-www-form-urlencoded //浏览器表单默认
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=31234
Content-Type: multipart/form-data, //body中有多种格式
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...

------WebKitFormBoundaryrGKCBY7qhFd3TrwA--12345678910111213

Body的压缩

因为 HTTP 在传输时为了节约 带宽,有时候还会压缩数据,为了不要让浏览器继 续“猜”,还需要有一个“Encoding type”,告诉数据是 用的什么编码格式,这样对方才能正确解压缩,还原出原始 的数据。常用的是gzip.

大文件传输-分开传输

如果大文件整体不能变小,那就把它“拆开”,分解成多个小块,把 这些小块分批发给浏览器,浏览器收到后再组装复原。 这种“化整为零”的思路在 HTTP 协议里就 是“chunked”分块传输编码,在响应报文里用头字 段“Transfer-Encoding: chunked”来表示,“Transfer-Encoding: chunked”和“Content-Length”这两个字段是互斥的,也就是说响应报文里这两 个字段不能同时出现,一个响应报文的传输要么是长度已 知,要么是长度未知(chunked),这一点你一定要记住。

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

比如传输一个视频,你想跳过片头,直接看后面的剧情。就可以使用范围请求。只请求大文件的某些片段。HTTP 协议为了满足这样的需求,提出了“范围请 求”(range requests)的概念,允许客户端在请求头里使 用专用字段来表示只获取文件的一部分。web服务器必须在响应头里使用字段“AcceptRanges: bytes”明确告知客户端:“我是支持范围请求 的”。

请求头Range是 HTTP 范围请求的专用字段,格式 是“bytes=x-y”,其中的 x 和 y 是以字节为单位的数据范围。x为起点,y为终点。x-y必须合法才行,不能超出文件范围,不然服务器返回状态码416(请求超出范围)

如果请求合法,服务器返回状态码“206 Partial Content”,添加一个响应头字段Content-Range,告诉片段的实际偏移量和资源的总大小,格式是“bytes x-y/length”。

多段数据请求,request头的Range可以有多个x-y,表示一次请求多段数据。这时候响应MIME 类 型:“multipart/byteranges”,表示报文的 body 是由 多段字节序列组成的,并且还要用一个参 数“boundary=xxx”给出段之间的分隔标记。

Http的长连接-keep alive

正常情况下,一个http请求,首先底层的tcp连接需要三次握手建立连接,然后才是传输请求数据,然后返回响应数据,tcp连接断开。HTTP/1.1 中的连接都会默认启用长连接,请求头使用的字段是Connection,值是“keep-alive”。这样服务器返回响应数据后,tcp并不会马上断开连接,下次发起http请求就不用tcp三次握手建立连接。

但是 TCP 连接长时间不关闭,服务器必须在内存里保存它 的状态,这就占用了服务器的资源。

客户端主动关闭连接

可以在请求头里加上“Connection: close”字 段,告诉服务器:“这次通信后就关闭连接”。服务器看到 这个字段,就知道客户端要主动关闭连接,于是在响应报文 里也加上这个字段,发送之后就调用 Socket API 关闭 TCP 连接。

nginx通过设置,主动关闭连接

1.使用“keepalive_timeout”指令,设置长连接的超时时间

  1. 使用“keepalive_requests”指令,设置长连接上可发送 的最大请求次数。比如设置成 1000,那么当 Nginx 在这 个连接上处理了 1000 个请求后,也会主动断开连接。

重定向

是由服务器来发起的,浏览器使用者无法控制,当浏览器发起一个请求时,服务器处理的时候做重定向操作,就会响应3xx状态,响应头包含一个Location标识重定向的uri.此时浏览器会向这个uri发起请求。

永久重定向301

意思 是原 URI 已经“永久”性地不存在了,今后的所有请求都必须改用新的URI。浏览器看到 301,就知道原来的 URI“过时”了,就会做适 当的优化。比如历史记录、更新书签,下次可能就会直接用 新的 URI 访问,省去了再次跳转的成本。搜索引擎的爬虫看 到 301,也会更新索引库,不再使用老的 URI。

其实就是告诉请求方,这个站点uri的变化。如果一个站点准备变更域名,旧域名最好用永久重定向。这样旧站点的权重还会继承到新域名中,有利于seo。

临时重定向302

浏览器的url并没有改变

https协议

HTTPS协议 = HTTP协议 + SSL/TLS协议,在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输,由此可以看出HTTPS是由HTTP和SSL/TLS一起合作完成的。

HTTPS为了兼顾安全与效率,同时使用了对称加密和非对称加密。数据是被对称加密传输的,对称加密过程需要客户端的一个密钥,为了确保能把该密钥安全传输到服务器端,采用非对称加密对该密钥进行加密传输,总的来说,对数据进行对称加密,对称加密所要使用的密钥通过非对称加密传输。

服务器端的公钥和私钥,用来进行非对称加密

客户端生成的随机密钥,用来进行对称加密

先走TLS协议

  1. 确定对称加密公钥
  2. 验证网站证书是否合法
TLS协议有三次握手

http协议

1.客户端向端口443发起[Client Hello] 消息,附带信息有TLS版本+随机数(Client Random)+支持的密码套件。服务端收到信息马上会ACK.

2.当服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否⽀持,和从密码套件列表中选择⼀个密码 套件,以及⽣成随机数,向客户端回复[Server Hello]消息,附带信息 TLS版本+随机数(Server Random)+确认使用的密码套件。再回复「Server Certificate」消息,附带自己的证书,最后在发送一个[Server Hello Done].

3.客户端会验证服务器的证书是否合法,如果合法就会向服务器发送[Client Key Exchange]消息,附带的信息是被RSA公钥加密的随机数(pre-master), 服务端收到后用RSA私钥解密。

⾄此,客户端和服务端双⽅都共享了三个随机数,分别是 Client Random、Server Random、pre-master。 于是,双⽅根据已经得到的三个随机数,⽣成会话密钥(Master Secret),它是对称密钥,⽤于对后续的 HTTP 请求/响应的数据加解密

客户端再发送[Change Cipher Spec]告诉服务端开始使⽤加密⽅式发送消息,然后发一个[Encrypted Handshake Message]消息,把之前所有发送的数据做个摘要,再用会话密钥(master secret)加密⼀下,让服务器做个验证,验证加密通信是否可⽤和之前握⼿信息是否有 被中途篡改过。

4.服务端也是发送[Change Cipher Spec],[Encrypted Handshake Message]

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~