极客时间 - (应用层) HTTP 学习笔记

本文是极客时间关于应用层 HTTP 的学习笔记。介绍了 URL 格式,阐述了 HTTP 请求的准备、构建、发送过程,包括 DNS 解析、TCP 连接建立、请求报文组成及不同请求类型等。还说明了 HTTP 返回的构建,如状态码含义、返回首部信息,最后讲述了完整的请求与返回流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

极客时间 - (应用层) HTTP 学习笔记

http://www.163.com 是个 URL,叫作统一资源定位符。之所以叫统一,是因为它是有格式的。HTTP 称为协议,www.163.com 是一个域名,表示互联网上的一个位置。有的 URL 会有更详细的位置标识,例如 http://www.163.com/index.html 。正是因为这个东西是统一的,所以当你把这样一个字符串输入到浏览器的框里的时候,浏览器才知道如何进行统一处理。

HTTP 请求的准备

  • 浏览器会将 www.163.com 这个域名发送给 DNS 服务器,让它解析为 IP 地址。

  • HTTP 是基于 TCP 协议的,通过三次握手,是要先建立 TCP 连接了

  • 目前使用的 HTTP 协议大部分都是 1.1。在 1.1 的协议里面,默认是开启了 Keep-Alive 的,这样建立的 TCP 连接,就可以在多次请求中复用。

HTTP 请求的构建

HTTP 的报文大概分为三大部分。第一部分是请求行,第二部分是请求的首部,第三部分才是请求的正文实体。

1、请求行

对于访问网页来讲,最常用的类型就是GET。顾名思义,GET 就是去服务器获取一些资源。对于访问网页来讲,要获取的资源往往是一个页面。其实也有很多其他的格式,比如说返回一个JSON 字符串,到底要返回什么,是由服务器端的实现决定的。

例如,在云计算中,如果我们的服务器端要提供一个基于 HTTP 协议的 API,获取所有云主机的列表,这就会使用 GET 方法得到,返回的可能是一个 JSON 字符串。字符串里面是一个列表,列表里面是一项的云主机的信息。

另外一种类型叫做POST。它需要主动告诉服务端一些信息,而非获取。要告诉服务端什么呢?一般会放在正文里面。正文可以有各种各样的格式。常见的格式也是 JSON。

例如,我们下一节要讲的支付场景,客户端就需要把“我是谁?我要支付多少?我要买啥?”告诉服务器,这就需要通过 POST 方法。

还有一种类型叫PUT,就是向指定资源位置上传最新内容。但是,HTTP 的服务器往往是不允许上传文件的,所以 PUT 和 POST 就都变成了要传给服务器东西的方法。

例如,云主机已经创建好了,我想对这个云主机打一个标签,说明这个云主机是生产环境的,另外一个云主机是测试环境的。那怎么修改这个标签呢?往往就是用 PUT 方法。

再有一种常见的就是DELETE。这个顾名思义就是用来删除资源的。例如,我们要删除一个云主机,就会调用 DELETE 方法。

2、首部字段

1、请求首部字段

	Accept                         用户代理可处理的媒体类型
	Accept-Charset            	   优先的字符集
	Accept-Encoding                优先的内容编码
	Accept-Language                优先的语言(自然语言)
	Authorization                  Web认证信息
	Expect                         期待服务器的特定行为
	From                           用户的电子邮箱地址
	Host                           请求资源所在服务器
	If-Match                       比较实体标记(ETag)
	If-Modified-Since          	   比较资源的更新时间
	If-None-Match                  比较实体标记(与 If-Match 相反)
	If-Range                       资源未更新时发送实体 Byte 的范围请求
	If-Unmodified-Since            比较资源的更新时间(与If-Modified-Since相反)
	Max-Forwards                   最大传输逐跳数
	Proxy-Authorization            代理服务器要求客户端的认证信息
	Range                          实体的字节范围请求
	Referer                        对请求中 URI 的原始获取方
	TE                             传输编码的优先级
	User-Agent                     HTTP 客户端程序的信息

2、响应首部字段

	Accept-Ranges                 是否接受字节范围请求
	Age                           推算资源创建经过时间
	ETag                          资源的匹配信息
	Location                      令客户端重定向至指定URI
	Proxy-Authenticate            代理服务器对客户端的认证信息
	Retry-After                   对再次发起请求的时机要求
	Server HTTP                   服务器的安装信息
	Vary                          代理服务器缓存的管理信息
	WWW-Authenticate              服务器对客户端的认证信息

3、实体首部字段

	Allow                         资源可支持的HTTP方法
	Content-Encoding       		  实体主体适用的编码方式
	Content-Language              实体主体的自然语言
	Content-Length                实体主体的大小(单位:字节)
	Content-Location              替代对应资源的URI
	Content-MD5                   实体主体的报文摘要
	Content-Range                 实体主体的位置范围
	Content-Type                  实体主体的媒体类型
	Expires                       实体主体过期的日期时间
	Last-Modified                 资源的最后修改日期时间

HTTP 请求的发送

HTTP 协议是基于 TCP 协议的,所以它使用面向连接的方式发送请求,通过 stream 二进制流的方式传给对方。当然,到了 TCP 层,它会把二进制流变成一个的报文段发送给服务器。

在发送给每个报文段的时候,都需要对方有一个回应 ACK,来保证报文可靠地到达了对方。如果没有回应,那么 TCP 这一层会进行重新传输,直到可以到达。同一个包有可能被传了好多次,但是 HTTP 这一层不需要知道这一点,因为是 TCP 这一层在埋头苦干。

TCP 层发送每一个报文的时候,都需要加上自己的地址(即源地址)和它想要去的地方(即目标地址),将这两个信息放到 IP 头里面,交给 IP 层进行传输。

IP 层需要查看目标地址和自己是否是在同一个局域网。如果是,就发送 ARP 协议来请求这个目标地址对应的 MAC 地址,然后将源 MAC 和目标 MAC 放入 MAC 头,发送出去即可;如果不在同一个局域网,就需要发送到网关,还要需要发送 ARP 协议,来获取网关的 MAC 地址,然后将源 MAC 和网关 MAC 放入 MAC 头,发送出去。

网关收到包发现 MAC 符合,取出目标 IP 地址,根据路由协议找到下一跳的路由器,获取下一跳路由器的 MAC 地址,将包发给下一跳路由器。

这样路由器一跳一跳终于到达目标的局域网。这个时候,最后一跳的路由器能够发现,目标地址就在自己的某一个出口的局域网上。于是,在这个局域网上发送 ARP,获得这个目标地址的MAC 地址,将包发出去。

目标的机器发现 MAC 地址符合,就将包收起来;发现 IP 地址符合,根据 IP 头中协议项,知道自己上一层是 TCP 协议,于是解析 TCP 的头,里面有序列号,需要看一看这个序列包是不是我要的,如果是就放入缓存中然后返回一个 ACK,如果不是就丢弃。

TCP 头里面还有端口号,HTTP 的服务器正在监听这个端口号。于是,目标机器自然知道是HTTP 服务器这个进程想要这个包,于是将包发给 HTTP 服务器。HTTP 服务器的进程看到,原来这个请求是要访问一个网页,于是就把这个网页发给客户端。

HTTP 返回的构建

状态码会反应 HTTP 请求的结果。“200”意味着大吉大利;而我们最不想见的,就是“404”,也就是“服务端无法响应这个请求”。然后,短语会大概说一下原因。

接下来是返回首部的key value。这里面,Retry-After表示,告诉客户端应该在多长时间以后再次尝试一下。“503 错误”是说“服务暂时不再和这个值配合使用”。在返回的头部里面也会有Content-Type,表示返回的是 HTML,还是 JSON。

构造好了返回的 HTTP 报文,接下来就是把这个报文发送出去。还是交给 Socket 去发送,还是交给 TCP 层,让 TCP 层将返回的 HTML,也分成一个个小的段,并且保证每个段都可靠到达。

这些段加上 TCP 头后会交给 IP 层,然后把刚才的发送过程反向走一遍。虽然两次不一定走相同的路径,但是逻辑过程是一样的,一直到达客户端。

客户端发现 MAC 地址符合、IP 地址符合,于是就会交给 TCP 层。根据序列号看是不是自己要的报文段,如果是,则会根据 TCP 头中的端口号,发给相应的进程。这个进程就是浏览器,浏览器作为客户端也在监听某个端口。

当浏览器拿到了 HTTP 的报文。发现返回“200”,一切正常,于是就从正文中将 HTML 拿出来。HTML 是一个标准的网页格式。浏览器只要根据这个格式,展示出一个绚丽多彩的网页。这就是一个正常的 HTTP 请求和返回的完整过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

stark张宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值