小结
- 域名使用字符串来代替 IP 地址,方便用户记忆,本质上一个名字空间系统;
- DNS 就像是我们现实世界里的电话本、查 台,统管着互联 世界里的所有 站,是一
个“超级大管家”; - DNS 是一个树状的分布式查询系统,但为了提高查询效率,外围有多级的缓存;
- 使用 DNS 可以实现基于域名的负载均衡,既可以在内 ,也可以在外 。
自己动手,搭建HTTP实验环境
- 现实的 络环境太复杂,有很多干扰因素,搭建“最小化”的环境可以快速抓住重点,
掌握 HTTP 的本质; - 我们选择 Wireshark 作为抓包工具,捕获在 TCP/IP 协议栈中传输的所有流量;
- 我们选择 Chrome 或 Firefox 浏览器作为 HTTP 协议中的 user agent;
- 我们选择 OpenResty 作为 Web 服务器,它是一个 Nginx 的“强化包”,功能非常丰
富; - Telnet 是一个命令行工具,可用来登录主机模拟浏览器操作;
- 在 GitHub 上可以下载到本专栏的专用项目源码,只要把 OpenResty 解压到里面即可完
成实验环境的搭建。
键入 址再按下回车,后面究竟发生了什么/h2>
header
- HTTP的header一般都很大,HTTP 文经常是只有 header 而没 body
- 不过这个“大头”也不能太大,虽然 HTTP 协议对 header的大小没有做限制
请求行
header
- HTTP的header一般都很大,HTTP 文经常是只有 header 而没 body
- 不过这个“大头”也不能太大,虽然 HTTP 协议对 header的大小没有做限制
请求行
描述了客户端想要如何操作服务器端的资源。GET / HTTP/1.1,由请求方法,请求目标,版本 组成
状态行
服务器响应的状态。HTTP/1.1 200 OK,由版本 ,状态码,和原因组成
头部字段
唯一的区别是起始行
GET /09-1 HTTP/1.1
Host: www.chrono.com
GET /09-1 HTTP/1.1
Host : www.chrono.com
Host后面一定要接着:,不然就会 400 Bad Request
小结
- HTTP 文结构就像是“大头儿子”,由“起始行 + 头部 + 空行 + 实体”组成,简单地说就是“header+body”;
- HTTP 文可以没有 body,但必须要有 header,而且header 后也必须要有空行,形象地说就是“大头”必须要带着“脖子”;
- 请求头由“请求行 + 头部字段”构成,响应头由“状态行 + 头部字段”构成;
- 请求行有三部分:请求方法,请求目标和版本 ;
- 状态行也有三部分:版本 ,状态码和原因字符串;
- 头部字段是 key-value 的形式,用“:”分隔,不区分大小写,顺序任意,除了规定的标准头,也可以任意添加自
定义字段,实现功能扩展; - HTTP/1.1 里唯一要求必须提供的头字段是 Host,它必须出现在请求头里,标记虚拟主机名。
应该如何理解请求方法
目前 HTTP/1.1 规定了八种方法,单词都必须是大写的形式:
- GET:获取资源,可以理解为读取或者下载数据;
- HEAD:获取资源的元信息;
- POST:向资源提交数据,相当于写入或上传数据;
- PUT:类似 POST;
- DELETE:删除资源;
- CONNECT:建立特殊的连接隧道;
- OPTIONS:列出可对资源实行的方法;
- TRACE:追踪请求 – 响应的传输路径。
请求其实就相当于指示,由客户端发出,但是决定权在服务端那里。
GET和HEAD
HEAD与GET类试,但是HEAD只获取资源的元信息,HEAD被看成是GET的简化版。例如:比如,想要检查一个文件是否存在,只要发个 HEAD 请求就可以了,没有必要用 GET 把整个文件都取下来。再比如,要检查文件是否有最新版本,同样也应该用 HEAD,服务器会在响应头里把文件的修改时间传回来。
POST/PUT
PUT 的作用与 POST 类似,也可以向服务器提交数据,但与 POST 存在微妙的不同,通常 POST 表示的是“新建”“create”的含义,而 PUT 则是“修改”“update”的含义。
安全与幂等
在 HTTP 协议里,所谓的“安全”是指请求方法不会“破”服务器上的资源,即不会对服务器上的资源造成实质的
修改。例如,GET和HEAD是获取,不会造成损害,而POST和PUT就会修改资源。
所谓的“幂等”实际上是一个数学用语,被借用到了 HTTP协议里,意思是多次执行相同的操作,结果也都是相同的,即多次“幂”后结果“相等”。
POST 是“新增或提交数据”,多次提交数据会创建多个资源,所以不是幂等的;
PUT是“替换或更新数据”,多次更新一个资源,资源还是会第一次更新的状态,所以是幂等的
POST 理解成 INSERT,把 PUT 理解成 UPDATE
小结
- 请求方法是客户端发出的、要求服务器执行的、对资源的一种操作;
- 请求方法是对服务器的“指示”,真正应如何处理由服务器来决定;
- 最常用的请求方法是 GET 和 POST,分别是获取数据和发送数据;
- HEAD 方法是轻量级的 GET,用来获取资源的元信息;
- PUT 基本上是 POST 的同义词,多用于更新数据;
- “安全”与“幂等”是描述请求方法的两个重要属性,具有理论指导意义,可以帮助我们设计系统。
你能写出正确的 址吗/h2>
URI 不完全等同于 址,它包含有 URL 和 URN两个部分. 址实际上是 URL
URI 的格式
URI 本质上是一个字符串,这个字符串的作用是唯一地标记资源的位置或者名字
主机名之前的**身份信息“user:passwd@”**因为它把敏感信息以明文形式暴露出来,存在严重的安全隐患(一斤不使用了)
第二个多出的部分是查询参数后的片段标识符“#fragment”。片段标识符仅能由浏览器这样的客户端使用,服务器是看
不到的。所以也不会存在
URI 的编码
URI 转义的规则有点“简单粗暴”,直接把非 ASCII 码或特殊字符转换成十六进制字节值,然后前面再加上一个“%”。
小结
-
URI 是用来唯一标记服务器上资源的一个字符串,通常也称为 URL;
-
URI 通常由 scheme、host:port、path 和 query 四个部分组成,有的可以省略;
-
scheme 叫**“方案名”或者“协议名”**,表示资源应该使用哪种协议来访问;
-
“host:port”表示资源所在的主机名和端口 ;
-
path 标记资源所在的位置;
-
query 表示对资源附加的额外要求;
-
在 URI 里对“@&/”等特殊字符和汉字必须要做编码,否则服务器收到 HTTP 文后会无法正确处理。
-
HTTP 协议允许在在请求行里使用完整的 URI,但为什么浏览器没有这么做呢/p>
没有必要,因为在请求头的字段中都有,没必要重复
-
URI 的查询参数和头字段很相似,都是 key-value 形式,都可以任意自定义,那么它们在使用时该如何区别呢/p>
query参数针对的是资源(uri),而字段针对的是本次请求,也就是 文。
一个是长期、稳定的,一个是短期、临时的。
响应状态码该怎么用/h2>
HTTP有哪些优点有哪些缺点/h2>
-
简单、灵活、易于扩展(最重要也是最突出),容易上手,heder字段,状态码,还有body数据等都可以自己修改和扩展
-
应用广泛、环境成熟从台式机上的浏览器到手机上的各种 APP,从看新闻、泡论坛到购物、理财、“吃鸡”,你很难找到一个没有使用 HTTP 的地方。
-
无状态,
-
优点:所以就不需要额外的资源来记录状态信息,不仅实现上会简单一些,而且还能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。很容易地组成集群(负载均衡),一位内服务器都是相同的(无状态)。不会因为状态不一致导致处理出错。
-
缺点:无法支持需要连续多个步骤的“事务”操作,例如电商项目中的,添加购物车其实是要验证登陆的(要知道用户的身份),但是,如果每次都询问一遍身份信息就太麻烦了,还要增加了数据的传输量。从而有了cookie技术
-
明文,协议里的 文(准确地说是 header 部分)不使用二进制数据,而是用简单可阅读的文本形式。
-
优点:为我们的开发调试工作带来极大的便利
-
缺点:毫无隐私可言
-
不安全,与“明文”缺点相关但不完全等同的另一个缺点是“不安全”。HTTP 协议也不支持“完整性校验”,数据在传输过程中容易被窜改而无法验证真伪。为了解决 HTTP 不安全的缺点,所以就出现了 HTTPS,这个我们以后再说。
-
性能,不算差,不够好,当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据
小结
- HTTP 最大的优点是简单、灵活和易于扩展;
- HTTP 拥有成熟的软硬件环境,应用的非常广泛,是互联 的基础设施;
- HTTP 是无状态的,可以轻松实现集群化,扩展性能,但有时也需要用 Cookie 技术来实现“有状态”;
- HTTP 是明文传输,数据完全肉眼可见,能够方便地研究分析,但也容易被窃听;
- HTTP 是不安全的,无法验证通信双方的身份,也不能判断 文是否被窜改;
- HTTP 的性能不算差,但不完全适应现在的互联 ,还有很大的提升空间。
海纳百川:HTTP的实体数据
- 优点:所以就不需要额外的资源来记录状态信息,不仅实现上会简单一些,而且还能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。很容易地组成集群(负载均衡),一位内服务器都是相同的(无状态)。不会因为状态不一致导致处理出错。
- 缺点:无法支持需要连续多个步骤的“事务”操作,例如电商项目中的,添加购物车其实是要验证登陆的(要知道用户的身份),但是,如果每次都询问一遍身份信息就太麻烦了,还要增加了数据的传输量。从而有了cookie技术
- 优点:为我们的开发调试工作带来极大的便利
- 缺点:毫无隐私可言
从 HTTP 的 body 谈起。
数据类型与编码
MIME 把数据分成了八大类(MIME 是一个很大的标准规范,但HTTP知识取了其中的一部分)
- text,即文本格式的可读数据
- image,图像文件
- audio/video,音频和视频数据
-
application,数据格式不固定,可能是文本也可能是二进制,必须由上层应用程序来解释。常见的有
application/json,application/javascript、application/pdf 等
因为 HTTP 在传输时为了节约带宽,有时候还会压缩数据,为了不要让浏览器继续“猜”,还需要有一个“Encoding type”,告诉数据是用的什么编码格式,这样对方才能正确解压缩,还原出原始的数据。
- gzip,最流行的格式,nginx也一般用这个
- deflate,流行程度仅次于gzip
- br,一种专门为 HTTP 优化的新压缩算法
数据类型使用的头字段
- 数据类型表示实体数据的内容是什么,使用的是 MIMEtype(可以类比成你快递的物品),相关的头字段是 Accept(告诉服务器,客户端支持什么类型,以防服务器发过来的数据不认识,凡是有返回就可以带上) 和 Content-Type(请求和响应里都可以用,作用是指明body数据的类型,凡是有body数据都要带上);
- 数据编码表示实体数据的压缩方式,相关的头字段是Accept-Encoding 和 Content-Encoding;(可以类比成物品的包装方式)
- 语言类型表示实体数据的自然语言,相关的头字段是Accept-Language 和 Content-Language;
- 字符集表示实体数据的编码方式,相关的头字段是Accept-Charset 和 Content-Type;
- 客户端需要在请求头里使用 Accept 等头字段与服务器进行“内容协商”,要求服务器返回最合适的数据;
- Accept 等头字段可以用“,”顺序列出多个可能的选项,还可以用“;q=”参数来精确指定权重。
把大象装进冰箱:HTTP传输大文件的方法
数据压缩
对处理视频,音频这些媒体数据的效果不佳。但是处理文本还是不错的。在Nginx 里就会使用“gzip on”指令,启用对“text/html”的压缩。
分块传输
‘这种“化整为零”的思路在 HTTP 协议里就是“chunked”分块传输编码,在响应 文里用头字段“Transfer-Encoding: chunked”来表示,意思是 文里的 body 部分不是一次性发过来的,而是分成了许多的块(chunk)逐个发送。
分块传输也可以用于“流式数据”(就是stream,它像从源头持续不断地,慢慢地”流“过来的,而不是一次性,一整块发过来的),对于未知长度的数据,还是挺好用的“Transfer-Encoding: chunked”和“Content-
Length”这两个字段是互斥的。这里补充一下:举个例子,从GitHub上下载源码包,GitHub要实时压缩实时发送,而不是一下子压缩好再发送,这样body的长度一开始就是未知的。所以就要用分块编码,压缩一部分,就发一部分,这部分的长度是已知的,但总长度只有压缩完才能知道。chunked编码用在“流式”收发数据的时候,通常数据是即时生成的,也就是动态数据。
小结
- 分块传输可以流式收发数据,节约内存和带宽,使用响应头字段“Transfer-Encoding: chunked”来表示,分块的格式是 16 进制长度头 + 数据块;
- 范围请求可以只获取部分数据,即“分块请求”,实现视频拖拽或者断点续传,使用请求头字段“Range”和响应头字段“Content-Range”,响应状态码必须是 206;这个“Content-Range”针对的是原文的数据,与压缩后的数据无关,因为我们在看视频的时候,拖拽进度条,拖拽的是原视频的长度,而不是压缩后的长度。
- 也可以一次请求多个范围,这时候响应 文的数据类型是“multipart/byteranges”,body 里的多个部分会用boundary 字符串分隔。
排队也要讲效率:HTTP的连接管理
短连接
因为客户端与服务器的整个连接过程很短暂,不会与服务器保持长时间的连接状态
长连接
用的就是**“成本均摊”的思路,既然 TCP 的连接和关闭非常耗时间,那么就把这个时间成本由原来的一个“请求 – 应答”均摊到多个“请求 – 应答”上**。
连接相关的头字段
由于长连接对性能的改善效果非常显著,所以在 HTTP/1.1中的连接都会默认启用长连接。“Connection: keepalive”
字段,服务器端通常不会主动关闭连接,但也可以使用一些策略。例如使用nginx的keepalive_timeout
队头阻塞
如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是其他的请求承担了不应有的时间成本。
性能优化
要解决队头阻塞,就要进行并发连接,缺陷就是:很容易造成连接数过多,而从被服务器认为是恶意攻击,反而造成”拒绝服务“。
域名分片,还是用数量来解决质量的思路。多开几个域名,而这些域名都指向同一台服务器。
小结
-
早期的 HTTP 协议使用短连接,收到响应后就立即关闭连接,效率很低;
-
HTTP/1.1 默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率;
-
服务器会发送**“Connection: keep-alive”字段表示启用了长连接**;
-
文头里如果有**“Connection: close”就意味着长连接即将关闭**;
-
过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接;
-
**“队头阻塞”问题会导致性能下降,可以用“并发连接”和“域名分片”**技术缓解。
四通八达:HTTP的重定向和跳转
跳转动作是由浏览器的使用者主动发起的,可以称为“主动跳转”
跳转是由服务器来发起的,称为“被动跳转”
以上方法统一叫“重定向”(Redirection)
重定向的过程
“Location”字段属于响应字段,必须出现在响应 文里。它标记了服务器要求重定向的 URI
注意,在重定向时如果只是在站内跳转,你可以放心地使用相对 URI。但如果要跳转到站外,就必须用绝对 URI。
重定向状态码
- 301俗称**“永久重定向”**意思是原 URI 已经“永久”性地不存在了,今后的所有请求都必须改用新的 URI。
- 302俗称“临时重定向”
- 303 See Other,要求重定向后的请求改为GET 方法
- 307 Temporary Redirect:,重定向后请求里的方法和实体不允许变动
- 308 Permanent Redirect:,不允许重定向后的请求变动,但它是 301“永久重定向”的含义
重定向的应用场景
一个最常见的原因就是“资源不可用”,需要用另一个新的URI 来代替。另一个原因就是“避免重复”
301:原来的 URI 已经不能用了(比如启用了新域名、服务器切换到了新机房、 站目录层次重构),必须用 301“永久重定向”
302:原来的 URI 在将来的某个时间点还会恢复正常,常见的应用场景就是系统维护。另一种用法就是“服务降级”,比如在双十一促销的时候,把订单查询、领积分等不重要的功能入口暂时关闭,保证核心服务能够正常运行。
重定向的相关问题
第一个问题是“性能损耗”,重定向应当适度使用,决不能滥用。
第二个问题是“循环跳转”,可能会出现“A=>B=>C=>A”的无限循环
小结
- 重定向是服务器发起的跳转,要求客户端改用新的 URI重新发送请求,通常会自动进行,用户是无感知的;
- 301/302 是最常用的重定向状态码,分别是“永久重定向”和“临时重定向”;
- 响应头字段 Location 指示了要跳转的 URI,可以用绝对或相对的形式;
- 重定向可以把一个 URI 指向另一个 URI,也可以把多个URI 指向同一个 URI,用途很多;
- 使用重定向时需要当心性能损耗,还要避免出现循环跳转。
一句话,转发是服务器行为,重定向是客户端行为。具体解释可以看这篇文章https://blog.csdn.net/meiyalei/article/details/2129120
让我知道你是谁:HTTP的Cookie机制
什么是 Cookie/h3>
相当于是服务器给每个客户端都贴上一张小纸条,上面写了一些只有服务器才能理解的数据,需要的时候客户端把这些信息发给服务器,服务器看到 Cookie,就能够认出对方是谁了。
Cookie 的工作过程
这要用到两个字段:响应头字段Set-Cookie和请求头字段Cookie。

Cookie 是由浏览器负责存储的,而不是操作系统。所以,它是“浏览器绑定”的,只能在本浏览器内生效
Cookie 的属性
首先,我们应该设置 Cookie 的生存周期,以使用 Expires 和 Max-Age 两个属性来设置。“Expires”俗称“过期时间”,用的是绝对时间点,可以理解为“截止日期”(deadline)。“Max-Age”用的是相对时间。Expires 和 Max-Age 可以同时出现,但浏览器会优先采用 Max-Age 计算失效期。
其次,我们需要设置 Cookie 的作用域,让浏览器仅发送给特定的服务器和 URI,避免被其他 站盗用
“Domain”和“Path”指定了 Cookie 所属的域名和路径,
最后要考虑的就是Cookie 的安全性了,尽量不要让服务器以外的人看到。
这些信息,在application面板都能看到
Cookie 的应用
- 身份识别
- 广告跟踪
小结
- Coo
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!