计算机网络2

十一、HTTP的特点

1. HTTP 是灵活可扩展的,可以任意添加头字段实现任意功能;
2. HTTP 是可靠传输协议,基于 TCP/IP 协议“尽量”保证数据的送达;
3. HTTP 是应用层协议,比 FTP、SSH 等更通用功能更多,能够传输任意数据;
4. HTTP 使用了请求 - 应答模式,客户端主动发起请求,服务器被动回复请求;
5. HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。

十二、HTTP的优点和缺点

1. HTTP 最大的优点是简单、灵活和易于扩展;
2. HTTP 拥有成熟的软硬件环境,应用的非常广泛,是互联网的基础设施;
3. HTTP 是无状态的,可以轻松实现集群化,扩展性能,但有时也需要用 Cookie 技术来实
现“有状态”;
4. HTTP 是明文传输,数据完全肉眼可见,能够方便地研究分析,但也容易被窃听;
5. HTTP 是不安全的,无法验证通信双方的身份,也不能判断报文是否被窜改;
6. HTTP 的性能不算差,但不完全适应现在的互联网,还有很大的提升空间

十三、HTPP的实体数据

1、数据类型与编码

MIME type 和 Encoding type 解决了计算机理解 body 数据的问题

在 TCP/IP 协议栈里,传输数据基本上都是“header+body”的格式。

 TCP、UDP 因为是传输层的协议,只要把数据发送到对方就算是完成了任务。

 HTTP 协议应用层的协议数据到达之后,还必须要告诉上层应用数据类型

MIME type:“多用途互联网邮件扩展”,用来标记 body 的数据类型

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

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/octet-stream,即不透明的二进制数据

HTTP 在传输时为了节约带宽,有时候还会压缩数据,还需要有一个“Encoding type”告诉数据是用的什么编码格式,对方才能正确解压缩,还原出原始的数据。

Encoding type:

1. gzip:GNU zip 压缩格式,也是互联网上最流行的压缩格式;
2. deflate:zlib(deflate)压缩格式,流行程度仅次于gzip;
3. br:一种专门为 HTTP 优化的新压缩算法(Brotli)

数据类型内容协商的头字段:Accept(数据类型)、Accept-Encoding(压缩方式,没有表示客户端不支持压缩数据)、Content-Type(数据类型,也可用在请求报文,POST方法时必须要用)、Content-Encoding(压缩方式,没有表示数据没有被压缩)

Accept 请求头字段和 Content实体头字段

2、语言类型与编码

语言与编码内容协商的头字段:Accept-Language、ContentLanguage、Accept-Charset、Content-Type字段的数据类型后面用“charset=xxx”

3、内容协商的质量值

q”参数表示权重来设定优先级,[0.01,1],默认值是 1,0表示拒绝。具体的形式是在数据类型或语言代码后面加一个“;”,然后是“q=value”.“;”的意义是小于“,”的

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

Vary 字段表示服务器依据了 Accept-Encoding、User-Agent 和 Accept 这三个头字段,然后决定了发回的响应报文,请求头变化时,Vary 也会随着响应报文一起变化。

十四、HTTP传输大文件的方法

1、数据压缩

压缩HTML等文本文件是传输大文件最基本的方法

2、分块传输

服务器化整为零,分块传输:响应报文里用头字段“Transfer-Encoding: chunked”来表示,意思是报文
里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送

流式数据:body 数据的长度是未知的,无法在头字段“Content-Length”里给出确切的长度,只能用 chunked 方式分块发送。

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

分块传输的编码规则:16进制长度头 + 数据块

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

3、范围请求

范围请求(range requests):允许客户端在请求头里使用Range头字段来表示只获取文件的一部分,客户端的“化整为零”

服务器支持范围请求:必须在响应头里使用字段“Accept-Ranges: bytes”;不支持“Accept-Ranges: none”或者没有此字段

范围请求格式:Range:bytes=x-y(x、y表示偏移量,从0开始;10-表示10到文件结尾,-1表示0到文件结尾倒数第二个)

服务器接收范围请求后:

1、检查范围,范围出界,返回416

2、范围正确,根据Range计算偏移量读取文件,返回206 PartialContent

3、添加一个响应头字段Content-Range:bytes x-y/length

4、发送数据

4、多段数据

一次请求多个范围

 请求头字段:Range:bytes=x-y,x-y

响应头字段Content-Type:multipart/byteranges(表示报文的 body 是由多段字节序列组成的);boundary=xxx(给出段之间的分隔标记)

Content-Range:bytes x-y/length

课后问题:

1、分块传输中数据里含有回车换行(\r\n)不影响分块处理,因为分块前有数据长度说明

2、如果对一个被 gzip 的文件执行范围请求,那么这个范围是应用于原文件还是压缩后的文件呢?

Range是针对原文件的

十五、HTTP的连接管理

1、短连接

短连接:HTTP协议底层的数据传输基于 TCP/IP,每次发送请求前需要先与服务器建立连接,收到响应报文后会立即关闭连接,连接过程很短暂。

缺点:事件都被浪费在建立好关闭连接上,传输效率太低。严重制约了服务器的服务能力,导致它无法处理更多的请求

2、长连接

长连接:用到了成本均摊的思路,一次建立连接中多次请求响应

长连接上发送的请求越多,利用率也就越高

3、连接相关的头字段

HTTP/1.1中的连接默认启用长连接

请求头里明确地要求使用长连接机制的字段:Connection: keep alive
服务器支持长连接,它总会在响应报文里放一个“Connection: keep alive”字段

长连接也需要在恰当的时间关闭,请求头里加上Connection: close,响应报文里也加上这个字段,发送之后就调用 Socket API 关闭 TCP连接。服务器端通常不会主动关闭连接

服务器可以使用一些策略主动关闭连接:

1. 使用“keepalive_timeout”指令设置长连接的超时时间,如果在一段时间内连接上没有任何数据收发就主动断开连接,避免空闲连接占用系统资源。
2. 使用“keepalive_requests”指令,设置长连接上可发送的最大请求次数。比如设置成 1000,那么当 Nginx 在这个连接上处理了 1000 个请求后,也会主动断开连接。

客户端和服务器都可以在报文里附加通用头字段“Keep-Alive: timeout=value”,限定长连接的超时时间

4、队头阻塞

队头阻塞”是由 HTTP 基本的“请求 - 应答”模型所导致的。形成了一个先进先出的“串行”队列。排在最前面的请求被最优先处理。
队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是其他的请求承担了不应有的时间成本

5、性能优化

a、并发连接:同时对一个域名发起多个长连接,用数量来解决质量的问题

b、域名分片:多开几个域名,域名都指向同一台服务器,长连接的数量又增加了

十六、HTTP的重定向和跳转

主动跳转:由浏览器的使用者主动发起

被动跳转:由服务器来发起

重定向可以把一个URI指向另一个URI,也可以把多个URI指向一个URI,用途很多

1、过程

过程:重定向”实际上发送了两次HTTP 请求,第一个请求返回了 302,然后第二个请求就被重定向到了“/index.html”。

重定向是服务器发起的跳转,要求客户端改用新的URI重新发送请求,通常自动进行,用户无感知。
第一次请求的响应头的头字段“Location: /index.html”指示了要跳转的URI,可以用相对或绝对的形式。

Location”字段属于响应字段,只有配合 301/302 状态码才有意义,标记了服务器要求重定向的 URI。
浏览器收到 301/302 报文,会检查响应头里有没有“Location”。如果有,就从字段值里提取出 URI,发出新的 HTTP 请求,相当于自动替我们点击了这个链接。

重定向时只是在站内跳转,用相对 URI。要跳转到站外,就必须用绝对 URI

2、状态码

301:“永久重定向”
302:“临时重定向”

303 See Other:类似 302要求重定向后的请求改为GET 方法,访问一个结果页面,避免POST/PUT 重复操作;
307 Temporary Redirect:类似 302,但重定向后请求里的方法和实体不允许变动,含义比 302 更明确;
308 Permanent Redirect:类似 307不允许重定向后的请求变动,但它是 301“永久重定向”的含义

3、应用场景

a、资源不可用

b、避免重复

大幅度的改变:永久

原来的 URI 在将来的某个时间点还会恢复正常:临时

4、相关问题

性能损耗:一个跳转会有两次请求 - 应答,比正常的访问多了一次。站内重定向还好说,可以长连接复用,站外重定向就要开两个连接

循环跳转:A=>B=>C=>A

十七、HTTP的Cookie机制

1、Cookie

Cookie 并不属于 HTTP 标准(RFC6265,而不是RFC2616/7230),所以语法上与其他字段不太一致,使用的分隔符是“;”

HTTP 协议有个特点是无状态不同请求间协议内容无相关性,即本次请求与上次请求没有内容
的依赖关系,本次响应也只针对本次请求的数据,至于服务器应用程序为用户保存的状态
是属于应用层,与协议是无关的。

Cookie :一种让HTTP 协议请求与请求之间建立起联系,并且服务器需要知道这个请求来自哪个用户的技术

2、Cookie工作过程

响应头字段Set-Cookie(key=value)和请求头字段Cookie

 Cookie 本质上就是一份存储在用户本地的文件(用于存储少量的不敏感的信息),里面包含了每次请求中都需要传递的信息。

3、Cookie属性

a、设置 Cookie 的生存周期

Expires:绝对时间点,截止日期(deadline)。

Max-Age:相对时间,单位是秒,浏览器用收到报文的时间点再加上 Max-Age,就可以得到失效的绝对时间(优先采用)

b、设置 Cookie 的作用域

Domain:指定 Cookie 所属的域名

Path:指定 Cookie 所属的路径

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

c、Cookie 的安全性

HttpOnly:Cookie 只能通过浏览器 HTTP 协议传输,禁止其他方式访问,浏览器的 JS 引擎就会禁用 document.cookie 等一切相关的 API

SameSite:可以防范“跨站请求伪造”(XSRF)攻击,设置成“SameSite=Strict”可以严格限定 Cookie 不能随着跳转链接跨站发送,而“SameSite=Lax”则略宽松一点,允许 GET/HEAD 等安全方法,但禁止 POST 跨站发送

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

4、Cookie应用

a、身份识别,实现有状态的会话事务

b、广告跟踪

5、Session和Cookie

Cookie 以明文的方式存储在本地,而 Cookie 中往往带有用户信息,这样就造成了非常大的安全隐患。

Session 翻译过来就是会话会话是指客户端与服务端进行通讯的过程,比如用户在浏览器中点击一个超链接访问 Web 资源,到关闭该标签页就是一个会话过程。

工作过程:

  • 客户端第一次请求,提交用户名密码等信息进行登录认证,服务器根据客户端提交的信息进行鉴权,鉴权成功后创建 Session 对象,用来保存相关数据,比如用户角色、登录时间等;
  • 服务器响应时将此 Session 的唯一标识信息 SessionID 返回给客户端,客户端接收到后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名
  • 客户端之后的每一次请求,浏览器都会自动将当前域名下的 Cookie 信息发送给服务器;
  • 服务器解析 Cookie,获取到 SessionID,查找与之对应的 Session 对象,如果 Session 对象存在说明用户已经登录,返回请求数据;
  • 如果 Session 对象不存在或已过期,展示错误信息,并返回登陆页面。

Cookie 是存储在客户端(Client),而 Session 保存在服务端(Server)。

SessionID 是 Cookie 和 Session 中间的一道桥梁,需要借助 Cookie 的传递才有意义。

CookieSession
存储方式Cookie 存储在客户端,方便与 JS 交互,方便获取用户信息。Session 存储在服务端,高效、安全,不依赖浏览器环境。
存储类型Cookie 只能存储字符串。Session 可以存储任意数据类型。
存储大小Cookie 大小有限制(4KB),同一域名下的数量也有限制(20 个)Session 没有类似的限制。
生命周期Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能。Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。
安全性Cookie 是本地存储,不是很安全,别人可以分析存放在本地的 Cookie 并进行欺骗,存在 CSRF 风险。
特点Cookie 是客户端存储用户信息的一种机制,用来记录用户的一些信息,也是实现 Session 的一种方式。Session 是在服务端存储的一个数据结构,用来跟踪用户的状态,这个数据可以保存在内存、文件、数据库中。
总结1. Cookie 遵循同源策略,不能跨域访问,除非特别部署。
2. SessionID 是客户端的唯一标识,存储在 Cookie 中,它是维持一个会话的核心。
3. Cookie 和 Session 都是为了在无状态的 HTTP 协议之上维护会话状态,使得服务端可以知道当前是和哪个客户在“打交道”。

其实,Cookie 和 Session 无法放在一起对比,因为它们维度不同,放在一起比较,容易误导别人造成混乱。

如果硬要进行比较,可把 Session 这一虚拟概念,分成两个实例,服务端 Session 和 客户端 Session,由服务端 Session 和 Cookie 进行比较(见上表)。

  • Cookie 是一个 HTTP 头部,而 Session 是一个虚拟概念。
  • Cookie 可以用于实现 Session,也可以不。反过来说,Session 也未必需要用 Cookie 实现。
  • Session 指的是客户端与服务端维持的一个有状态会话,和 Cookie 不是两种互斥的实现。
  • Session 不能说这是纯服务端的事情,跟客户端也有关,也需要 Cookie 的帮助。
  • 客户端 Session 即 SessionID,存储在 Cookie 中,所以也是 Cookie。
  • Cookie 按存储类型可分为会话 Cookie 和 持久化 Cookie,前者即 SessionID。

十八、HTTP的缓存控制

缓存(Cache)优化系统性能,HTTP 传输的每一个环节基本上都会有缓存

1、服务器的缓存控制

流程:

1. 浏览器发现缓存无数据,于是发送请求,向服务器获取资源
2. 服务器响应请求返回资源,同时标记资源的有效期
3. 浏览器缓存资源,等待下次重用。

服务器标记资源有效期使用的头字段是“Cache-Control”,里面的值“maxage=30”就是资源的有效时间,时间的计算起点是响应报文的创建时刻。

no_store:不允许缓存,用于某些变化非常频繁的数据,例如秒杀页面;
no_cache:可以缓存,但在使用之前必须要去服务器验证是否过期,是否有最新的版本
must-revalidate:如果缓存不过期就可以继续使用,但过期了如果还想用就必须去服务器验证

2、客户端的缓存控制

请求 - 应答的双方都可以用Cache-Control字段进行缓存控制,互相协商缓存的使用策略

“刷新”:浏览器会在请求头里加一个“Cache-Control: maxage=0”。max-age=0 的意思就是“我要一个最最新鲜的西瓜”,而本地缓存里的数据至少保存了几秒钟,所以浏览器就不会使用缓存,而是向服务器发请求。服务器看到 max-age=0,也就会用一个最新生成的报文回应浏览器

Ctrl+F5 的“强制刷新”:Cache-Control: no-cache”,含义和“max-age=0”基本一样。效果相同

“前进”“后退”“跳转”这些重定向动作中浏览器不会“夹带私货”,只用最基本的请求头,没有“Cache-Control”,所以就会检查缓存,直接利用之前的资源,不再进行网络通信

3、条件请求

HTTP 协议就定义了一系列“If”开头的“条件请求”字段,专门用来检查验证资源是否过期,把两个请求才能完成的工作合并在一个请求里做。

“if-Modified-Since”和“If-None-Match”。需要第一次的响应报文提供“Last-modified”(文件的最后修改时间)和“ETag”(精确地识别资源的变动情况),然后第二次请求时就可以带上缓存里的原值验证资源是否是最新的。如果资源没有变,服务器就回应一个“304 Not Modified”,表示缓存依然有效,浏览器就可以更新一下有效期,然后放心大胆地使用缓存了。

强 ETag 要求资源在字节级别必须完全相符,弱 ETag 在值前有个“W/”标记,只要求资源在语义上没有变化,但内部可能会有部分发生了改变

课后问题:

1. Cache 和 Cookie 都是服务器发给客户端并存储的数据,你能比较一下两者的异同吗?

Cache 和 Cookie 的相同点是:都会保存到浏览器中,并可以设置过期时间。
不同点:
1. Cookie 会随请求报文发送到服务器,而 Cache 不会,但可能会携带 if-Modified-Since(保存资源的最后修改时间)和 If-None-Match(保存资源唯一标识) 字段来验证资源是否过期。
2. Cookie 在浏览器可以通过脚本获取(如果 cookie 没有设置 HttpOnly),Cache 则无法在浏览器中获取(出于安全原因)。
3. Cookie 通过响应报文的 Set-Cookie 字段获得,Cache 缓存的是完整报文。
4. 用途不同。Cookie 常用于身份识别,Cache 则是由浏览器管理,用于节省带宽和加快响应度。
5. Cookie 的 max-age 是从浏览器拿到响应报文时开始计算的,而 Cache 的 max-age 是从响应报文的生成时间(Date 头字段)开始计算。

2. 即使有“Last-modified”和“ETag”,强制刷新(Ctrl+F5)也能够从服务器获取最新数据(返回 200 而不是 304),请你在实验环境里试一下,观察请求头和响应头,解释原因。
强制刷新,请求头里有Pragma: no-cache和Cache-Control: no-cache,没有IfModified-Since/If-None-Match,这个Pragma: no-cache的意思是禁用缓存

十九、HTTP的代理服务

1、代理服务(反向代理)

HTTP 代理就是客户端和服务器通信链路中的一个中间环节,为两端提供“代理服务”;
代理处于中间层,为 HTTP 处理增加了更多的灵活性,可以实现负载均衡、安全防护、数据过滤等功能

负载均衡:代理服务器就可以掌握请求分发的“大权”,决定由后面的哪台服务器来响应请求。负载均衡算法(轮询、一致性哈希),尽量把外部的流量合理地分散到多台源服务器,提高系统的整体资源利用率和性能。

2、代理相关头字段

a、字段“Via”标明代理的身份

通用字段,报文经过一个代理节点,就会追加代理主机名或者域名。Via: proxy1, proxy2

b、X-Forwarded-For

报文经过一个代理节点,就会追加请求方的 IP 地址

c、X-Real-IP:记录客户端 IP地址

d、X-Forwarded-Host:记录客户端请求的原始域名

e、X-Forwarded-Proto:记录客户端请求的原始协议名

3、代理协议

代理协议”可以在不改动原始报文的情况下传递客户端的真实 IP

代理协议在 HTTP 报文前增加了一行 ASCII 码文本,相当于又多了一个头。

格式:开头必须是“PROXY”五个大写字母,然后是“TCP4”或者“TCP6”,表示客户端的 IP 地址类型,再后面是请求方地址、应答方地址、请求方端口号、应答方端口号,最后用一个回车换行(\r\n)结束

服务器看到这样的报文,只要解析第一行就可以拿到客户端地址,不需要再去理会后面的HTTP 数据,省了很多事情

二十、HTTP的缓存代理

1、缓存代理服务

缓存代理是增加了缓存功能的代理服务,缓存源服务器的数据,分发给下游的客户端;

2、源服务器的缓存控制

a、Cache-Control”属性:max-age、no_store、no_cache 和 must-revalidate

b、“private”和“public”:区分客户端缓存和代理缓存

c、“must-revalidate”:只要过期就必须回源服务器验证,“proxy-revalidate”只要求代理的缓存过期后必须验证,客户端不必回源,只验证到代理这个环节就行了

d、s-maxage”:缓存的生存时间

e、no-transform:禁止代理对缓存数据修改

3、客户端的缓存控制

 max-stale:如果代理上的缓存过期了也可以接受,但不能过期太多,超过 x 秒
也会不要。

min-fresh:缓存必须有效,而且必须在 x 秒后依然有效。

only-if-cached:表示只接受代理缓存的数据,不接受源服务器的响应。如果代理上没有缓存或者缓存过期,就应该给客户端返回一个504(Gateway Timeout)
 




 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值