大话http(二)(上)

本文涉及的产品
.cn 域名,1个 12个月
简介: 大话http(二)

在大话http(一)中,我们学习了http的基本内容,下面这一篇文章将带你更加深入的了解http。


http的实体数据


TCP、UDP 因为是传输层的协议,它们不会关心 body 数据是什么,只要把数据发送到对方就算是完成了任务。


数据类型与编码


但是HTTP 协议则不同,它是应用层的协议。他除了传送数据之外,还必须告诉对方这个数据类型是什么。所以使用多用途互联网邮件扩展(Multipurpose Internet Mail Extensions),简称为 MIME。


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


  • text:即文本格式的可读数据,我们最熟悉的应该就是 text/html 了,表示超文本文档,此外还有纯文本 text/plain、样式表 text/css 等。


  • image:即图像文件,有 image/gif、image/jpeg、image/png 等。


  • audio/video:音频和视频数据,例如 audio/mpeg、video/mp4 等。


  • application:数据格式不固定,可能是文本也可能是二进制,必须由上层应用程序来解释。常见的有 application/json,application/javascript、application/pdf 等,另外,如果实在是不知道数据是什么类型,像刚才说的“黑盒”,就会是 application/octet-stream,即不透明的二进制数据。


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


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


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


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


对应的头部字段


HTTP 协议为此定义了两个 Accept 请求头字段和两个 Content 实体头字段,用于客户端和服务器进行“内容协商”。也就是说,客户端用 Accept 头告诉服务器希望接收什么样的数据,而服务器用 Content 头告诉客户端实际发送了什么样的数据。


  • Accept 字段标记的是客户端可理解的 MIME type,可以用“,”做分隔符列出多个类型,让服务器有更多的选择余地。


  • 服务器会在响应报文里用头字段 Content-Type 告诉实体数据的真实类型并且如果需要发送请求体,那么也需要指定Content-Type字段。


  • Accept-Encoding 字段标记的是客户端支持的压缩格式,例如上面说的 gzip、deflate 等,同样也可以用“,”列出多个。


  • 服务器可以选择其中一种来压缩数据,实际使用的压缩格式放在响应头字段 Content-Encoding 里。 Accept-encoding, Content-Encoding不是必须的。不指定表示不支持压缩数据,没有进行压缩。


内容协商机制


有了上面的mine encoding type,我们可以让浏览器知道如何解析数据。有时候,我们需要根据用户返回不同语言版本的网页。


网络异常,图片无法展示
|


内容协商方式


网络异常,图片无法展示
|


服务器驱动(常用)


网络异常,图片无法展示
|


网络异常,图片无法展示
|


近似匹配(通过q权重)


网络异常,图片无法展示
|


内容协商对应的头部字段


  • Accept-Language 字段标记了客户端可理解的自然语言。


  • 服务器应该在响应报文里用头字段 Content-Language 告诉客户端实体数据使用的实际语言类型


  • 字符集在 HTTP 里使用的请求头字段是 Accept-Charset但响应头里却没有对应的 Content-Charset,而是在 Content-Type 字段的数据类型后面用“charset=xxx”来表示,这点需要特别注意。在http头部字段中。,表示每一个字段值的分割,而;表示该字段值的分割。


Accept: text/html,application/xml;q=0.9,*/*;q=0.8


内容协商的过程是不透明的,每个 Web 服务器使用的算法都不一样。但有的时候,服务器会在响应头里多加一个 Vary 字段,记录服务器在内容协商时参考的请求头字段,给出一点信息。


http大文件传输方式


数据压缩


我们知道,http请求报文中可以指定accept-encoding字段来指定可以接收的压缩方式。然后服务器选择一种支持的压缩方式,并在响应报文中指定content-encoding字段,将元数据压缩后返回给浏览器。


gzip 等压缩算法通常只对文本文件有较好的压缩率,而图片、音频视频等多媒体数据本身就已经是高度压缩的,再用 gzip 处理也不会变小(甚至还有可能会增大一点),所以它就失效了。


分块传输


压缩是把大文件整体变小,我们可以反过来思考,如果大文件整体不能变小,那就把它“拆开”,分解成多个小块,把这些小块分批发给浏览器,浏览器收到后再组装复原

这种“化整为零”的思路在 HTTP 协议里就是“chunked”分块传输编码,在响应报文里用头字段 Transfer-Encoding: chunked 来表示,意思是报文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。


分块传输可以流式收发数据,节约内存和带宽,使用响应头字段“Transfer-Encoding: chunked”来表示,分块的格式是 16 进制长度头 + 数据块。


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


下面我们来看一下分块传输的编码规则,其实也很简单,同样采用了明文的方式,很类似响应头。


  • 每个分块包含两个部分,长度头和数据块;


  • 长度头是以 CRLF(回车换行,即\r\n)结尾的一行明文,用 16 进制数字表示长度;


  • 数据块紧跟在长度头后,最后也用 CRLF 结尾,但数据不包含 CRLF;


  • 最后用一个长度为 0 的块表示结束,即“0\r\n\r\n”。


网络异常,图片无法展示
|


服务器响应报文中的头部字段默认就是Transfer-Encoding: chunked


网络异常,图片无法展示
|


范围请求


比如,你在看当下正热播的某穿越剧,想跳过片头,直接看正片,或者有段剧情很无聊,想拖动进度条快进几分钟,这实际上是想获取一个大文件其中的片段数据,而分块传输并没有这个能力。所以就需要范围请求了。


有了范围请求之后,HTTP 处理大文件就更加轻松了,看视频时可以根据时间点计算出文件的 Range,不用下载整个文件,直接精确获取片段所在的数据内容。


范围请求不是 Web 服务器必备的功能,可以实现也可以不实现,所以服务器必须在响应头里使用字段Accept-Ranges: bytes明确告知客户端:“我是支持范围请求的”。


网络异常,图片无法展示
|


请求头 Range 是 HTTP 范围请求的专用字段,格式是bytes=x-y, 其中的 x 和 y 是以字节为单位的数据范围。格式非常灵活。x, y也可以省略。下面以100个字节的文件举例:


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


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


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


  • “-10”是从文档末尾倒数 10 个字节,相当于“90-99”。 服务器收到 Range 字段后,需要做四件事。


  • 第一,它必须检查范围是否合法,比如文件只有 100 个字节,但请求“200-300”,这就是范围越界了。服务器就会返回状态码 416,意思是“你的范围请求有误,我无法处理,请再检查一下”。


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


  • 第三,服务器要添加一个响应头字段Content-Range告诉片段的实际偏移量和资源的总大小,格式是“bytes x-y/length”,与 Range 头区别在没有“=”,范围后多了总长度。例如,对于“0-10”的范围请求,值就是“bytes 0-10/100”。


  • 最后剩下的就是发送数据了,直接把片段用 TCP 发给客户端,一个范围请求就算是处理完了。


网络异常,图片无法展示
|


断点续传的实现要点


  • 先发个HEAD请求,看服务器是否支持范围请求,同时获取文件的大小。主要是查看响应头中是否有accept-ranges: bytes


  • 开 N 个线程,每个线程使用 Range 字段划分出各自负责下载的片段,发请求传输数据;


  • 下载意外中断也不怕,不必重头再来一遍,只要根据上次的下载记录,用 Range 请求剩下的那一部分就可以了。


多段数据


我们再一次http请求中,也可以指定range的多个字段。表示请求多个数据片段。


这种情况需要使用一种特殊的 MIME 类型:multipart/byteranges,表示报文的 body 是由多段字节序列组成的,并且还要用一个参数“boundary=xxx”给出段之间的分隔标记。


网络异常,图片无法展示
|


每一个分段必须以“- -boundary”开始(前面加两个“-”),之后要用“Content-Type”和“Content-Range”标记这段数据的类型和所在范围。


HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=00000000001
Content-Length: 189
Connection: keep-alive
Accept-Ranges: bytes
Content-Type: text/plain
Content-Range: bytes 0-9/96


http长链接和短连接


短连接的缺点相当严重,因为在 TCP 协议里,建立连接和关闭连接都是非常“昂贵”的操作。TCP 建立连接要有“三次握手”,发送 3 个数据包,需要 1 个 RTT;关闭连接是“四次挥手”,4 个数据包需要 2 个 RTT。


在http启动长链接时。TCP 连接长时间不关闭,服务器必须在内存里保存它的状态,这就占用了服务器的资源。所以,长连接也需要在恰当的时间关闭,不能永远保持与服务器的连接,这在客户端或者服务器都可以做到。


  • 客户端,可以再请求头中加上Connection: close


  • 服务器端通常不会主动关闭连接,但也可以使用一些策略。


  • 设置长连接的超时时间,如果在一段时间内连接上没有任何数据收发就主动断开连接,避免空闲连接占用系统资源。


  • 设置长连接上可发送的最大请求次数。当在这次长链接中请求次数达到了,将主动关闭连接。


网络异常,图片无法展示
|


网络异常,图片无法展示
|


网络异常,图片无法展示
|


http的重定向


Location字段属于响应字段,必须出现在响应报文里。但只有配合 301/302 状态码才有意义,它标记了服务器要求重定向的 URI。


浏览器收到 301/302 报文,会检查响应头里有没有Location。如果有,就从字段值里提取出 URI,发出新的 HTTP 请求,相当于自动替我们点击了这个链接。


Location里的 URI 既可以使用绝对 URI,也可以使用相对 URI。相对URI是省略scheme, host:port,只有path, query部分。但是可以相对于当前上下文中找到对应的scheme, host,port。


注意,在重定向时如果只是在站内跳转,你可以放心地使用相对 URI。但如果要跳转到站外,就必须用绝对 URI。


301/302 是最常用的重定向状态码,在 3××里剩下的几个还有:


  • 303 See Other:类似 302,但要求重定向后的请求改为 GET 方法,访问一个结果页面,避免 POST/PUT 重复操作;


  • 307 Temporary Redirect:类似 302,但重定向后请求里的方法和实体不允许变动,含义比 302 更明确;


  • 308 Permanent Redirect:类似 307,不允许重定向后的请求变动,但它是 301“永久重定向”的含义。


重定向的选择


301 的含义是“永久”的。如果域名、服务器、网站架构发生了大幅度的改变,比如启用了新域名、服务器切换到了新机房、网站目录层次重构,这些都算是“永久性”的改变。原来的 URI 已经不能用了,必须用 301“永久重定向”,通知浏览器和搜索引擎更新到新地址,这也是搜索引擎优化(SEO)要考虑的因素之一。


302 的含义是“临时”的。原来的 URI 在将来的某个时间点还会恢复正常,常见的应用场景就是系统维护,把网站重定向到一个通知页面,告诉用户过一会儿再来访问。另一种用法就是“服务降级”,比如在双十一促销的时候,把订单查询、领积分等不重要的功能入口暂时关闭,保证核心服务能够正常运行。


重定向需要注意的问题


  • 性能损耗。重定向的机制决定了一个跳转会有两次请求 - 应答,比正常的访问多了一次。 虽然 301/302 报文很小,但大量的跳转对服务器的影响也是不可忽视的。站内重定向还好说,可以长连接复用,站外重定向就要开两个连接,如果网络连接质量差,那成本可就高多了,会严重影响用户的体验。


  • 循环跳转。如果重定向的策略设置欠考虑,可能会出现“A=>B=>C=>A”的无限循环。


HTTP状态管理


HTTP 是“无状态”的,这既是优点也是缺点。优点是服务器没有状态差异,可以很容易地组成集群,而缺点就是无法支持需要记录状态的事务操作。


http是无状态的,无记忆的。所以说每个请求都是独立的。如果其他请求处理需要以前请求的信息,那么就需要重新发送请求。导致每次连接传送的数据量增大。所以就需要cookie,session来保存http连接状态。


Cookie 就是服务器委托浏览器存储在客户端里的一些数据,而这些数据通常都会记录用户的关键识别信息。


网络异常,图片无法展示
|


cookie是如何进行传递的呢?就需要使用响应头字段 Set-Cookie 和请求头字段 Cookie。


用户第一次访问服务器时,服务器时不知道他的身份的,所以就创建一个key=value格式的文本。然后放在set-cookie字段中,返回给浏览器。浏览器看到set-cookie,就知道服务器给了身份标识。然后就将其保存到本地。下次再想服务器发送请求时,就把这些信息放在cookie字段中一同发送。


cookie的属性


Cookie 就是服务器委托浏览器存储在客户端里的一些数据,而这些数据通常都会记录用户的关键识别信息。


过期时间


  • max-age: 相对时间,单位是秒。浏览器用收到报文的时间点再加上 Max-Age,就可以得到失效的绝对时间。 这个优先级较高。


  • expires: 用的是绝对时间点,可以理解为截止日期。JMP格式。 如果不指定这两个字段,那么他们将是会话级别的。浏览器关闭,cookie就失效了。


作用域


让浏览器仅发送给特定的服务器和 URI,避免被其他网站盗用。


浏览器在发送 Cookie 前会从 URI 中提取出 host 和 path 部分,对比 Cookie 的属性。如果不满足条件,就不会在请求头里发送 Cookie。


  • domain:表示那些域名可以被发送cookie。


  • path:表示该域名下的那些路径可以发送cookie。如果为/则度可以接收到cookie。


安全性


在 JS 脚本里可以用 document.cookie 来读写 Cookie 数据,这就带来了安全隐患,有可能会导致“跨站脚本”(XSS)攻击窃取数据。


  • httpOnly:表示cookie只能通过浏览器 HTTP 协议传输,禁止其他方式访问。


  • SameSite 可以防范“跨站请求伪造”(XSRF)攻击,设置成“SameSite=Strict”可以严格限定 Cookie 不能随着跳转链接跨站发送,而“SameSite=Lax”则略宽松一点,允许 GET/HEAD 等安全方法,但禁止 POST 跨站发送。 这里你可能会有这种疑问。他这个是下面这种图片的意思。是你点击了超链接跳转的,而不是主动访问。然后就限制cookie发送给该服务器。


网络异常,图片无法展示
|


  • secure:表示这个 Cookie 仅能用 HTTPS 协议加密传输,明文的 HTTP 协议会禁止发送。但 Cookie 本身不是加密的,浏览器里还是以明文的形式存在。


cookie的用处


  • 身份标识。保存用户的登陆状态。


  • 广告跟踪。就是你在这个网页访问一个广告,那么该广告的服务器就下发了一个cookie,然后你再去别的页面,好巧,也有这个服务器的无广告,在请求这个广告的时候,就把以前的cookie放松到该广告的服务器。那么将推送很多的广告给你。


相关文章
|
2月前
|
网络协议 算法 数据安全/隐私保护
HTTP2和HTTP3区别?HTTP2有什么缺点?
总的来说,如果把HTTP/2比作是优化过的汽车,那HTTP/3就像是直升飞机,它不仅飞得快,而且即使前面有障碍也不会轻易停下。想要网站速度更快,HTTP/3无疑提供了更好的选择。
157 3
|
2月前
|
安全 网络安全 数据安全/隐私保护
http原理
http原理
28 3
|
6月前
|
存储 缓存 网络协议
说说 HTTP1.0/1.1/2.0 的区别?
HTTP协议从1.0到1.1再到2.0不断发展,提升了性能和效率。HTTP1.0每次请求需新建TCP连接,而1.1默认保持长连接,允许多个请求复用一个连接,减少延迟。HTTP2.0引入多路复用,允许同时发送多个请求和响应,避免队头堵塞;采用二进制分帧,提高解析效率;并使用首部压缩减少数据传输;此外,服务器推送功能允许预加载资源,优化加载速度。
127 0
|
6月前
|
安全 网络协议 前端开发
< 了解 HTTP 这一篇就够了 :什么是 HTTP ?HTTP 和 HTTPS 有什么区别 ? >
在前端开发中,是和浏览器打交道最为频繁的行业之一。但是大部分卷王们,可能仅仅是知道如何使用浏览器,只是知道 URL 跳转到浏览器变成一个完整的网页。 本篇文章将讲述 什么是HTTP、 HTTP 和 HTTPS的区别 及 URL 是如何渲染到页面。 那么到这里,肯定会有人问: 那我们为什么要学习这个呢 ? 问得好,这个分为两方面: 一是学习上述内容,能够厚实我们的理论基础。有些内容,虽然用的不多,但是技多不压身,道理懂吧? 二是学习这个,对我们后续的性能优化、排查浏览器上某些错误 的能力都有提升!
240 0
< 了解 HTTP 这一篇就够了 :什么是 HTTP ?HTTP 和 HTTPS 有什么区别 ? >
|
存储 缓存 网络协议
Http1.0和Http1.1的区别?Http1.1和Http2.0的区别
Http1.0和Http1.1的区别?Http1.1和Http2.0的区别
113 1
|
6月前
|
JSON 安全 算法
HTTP与HTTTPS的区别
HTTP与HTTTPS的区别
|
缓存 网络协议 开发者
HTTP1.0、HTTP1.1 、HTTP2.0和HTTP3.0 的区别【面试题】
HTTP1.0、HTTP1.1 、HTTP2.0和HTTP3.0 的区别【面试题】
1090 0
HTTP1.0、HTTP1.1 、HTTP2.0和HTTP3.0 的区别【面试题】
|
6月前
|
网络协议 算法
HTTP/1.1和HTTP/2.0有什么区别
HTTP/1.1和HTTP/2.0有什么区别
|
6月前
|
缓存 网络协议
HTTP/1.0和HTTP/1.1有什么区别
HTTP/1.0和HTTP/1.1有什么区别
|
域名解析 缓存 边缘计算