一次完整的HTTP请求
当我们在浏览器的地址栏输入 www.xmlwch.cn
,然后回车,回车这一瞬间到看到页面到底发生了什么呢?
个人理解至少需要经历以下步骤:
- 域名解析
- 建立TCP连接
- 浏览器向Web服务器发送请求命令
- Web服务器应答
- Web服务器关闭TCP连接
- 浏览器解析html代码
- 浏览器对页面进行渲染呈现给用户
1、域名解析
客户端根据访问的域名找到其IP地址。DNS查找过程如下:
- 浏览器缓存:首先搜索浏览器自身的DNS缓存(缓存的时间比较短,大概只有1分钟,且只能容纳1000条缓存),看自身的缓存中是否是有域名对应的条目,而且没有过期,如果有且没有过期则解析到此结束。
- 系统缓存:如果浏览器自身的缓存里面没有找到对应的条目,那么浏览器会搜索操作系统自身的DNS缓存,如果找到且没有过期则停止搜索解析到此结束。
- 路由器缓存:如果系统缓存也没有找到,则会向路由器发送查询请求。
- ISP(互联网服务提供商) DNS缓存:如果在路由缓存也没找到,最后要查的就是ISP缓存DNS的服务器。
2、建立TCP连接
浏览器与WEB服务器建立一个TCP连接,要经历完整的TCP3次握手,详细参考TCP 三次握手与四次挥手 中三次握手过程
3、浏览器向Web服务器发送请求命令
一个HTTP请求报文由请求行(request line)、请求头部(headers)、空行(blank line)和请求数据(request body)4个部分组成。
<method> <request-URL> <version> # 请求行
<headers> # 请求头部
# 空行
<entity-body> # 请求主体主要指请求数据
一个完整的请求报文:
GET / HTTP/1.1
Host: www.xmlwch.cn
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,...
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
3.1、请求行
请求行分为三个部分:请求方法、请求地址URL和HTTP协议版本,它们之间用空格分割。例如:
GET /index.html HTTP/1.1
3.1.1、请求方法
HTTP/1.1 定义的请求方法有8种,详细参考HTTP 请求方法
3.1.2、请求地址
URL:统一资源定位符,是一种资源位置的抽象唯一识别方法。
组成:<协议>://<主机>:<端口>/<路径>
端口和路径有时候会省略(HTTP 默认端口号是80,HTTPS 默认端口号是443)
# URL实例
http://localhost/index.php?key1=val1&key2=val2
# 协议: http; 主机: localhost; 路径: index.php; 参数: key1=val1&key2=val2
3.1.3、协议版本
协议版本的格式为:HTTP/主版本号.次版本号,常用的有HTTP/1.0和HTTP/1.1
3.2、请求头部
请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对,名和值之间使用冒号分隔。
请求头部的最后会有一个空行,表示请求头部结束,接下来为请求数据。
常用请求头可参考 HTTP 请求头
3.3、请求数据
请求数据不在GET方法中使用,而在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最长使用的请求头部是Cntent-Type和Content-Length。
4、Web服务器应答
HTTP响应报文由状态行(status line)、响应头部(headers)、空行(blank line)和响应数据(response body)4个部分组成。
<HTTP-Version> <Status-Code> <Reason-Phrase> # 状态行
<headers> # 响应头部
# 空行
<entity-body> # 响应主体即响应数据
一个完整的响应报文:
HTTP/1.1 200 OK
Server: nginx/1.20.0
Date: Wed, 11 Aug 2021 04:27:54 GMT
Last-Modified: Wed, 11 Aug 2021 03:13:50 GMT
Content-Type: text/html
ETag: W/"6113406e-61b4"
Content-Encoding: gzip
[....]
4.1、状态行
状态行由3部分组成,分别为:协议版本、状态码、状态码扫描。其中协议版本与请求报文一致,状态码描述是对状态码的简单描述。
状态码、状态码扫描详细参看 HTTP状态码
4.2、响应头部
响应头字段名 | 说明 |
---|---|
Server | 服务器应用程序的名称和版本 |
Content-Type | 响应正文的类型,可参见 HTTP Content Type | HTTP Media Type |
Content-Length | 响应正文长度 |
Content-Charset | 响应正文使用的编码 |
Content-Encoding | 响应正文使用数据压缩格式 |
Content-Language | 响应正文使用的语言 |
4.3、响应数据
用于存放需要返回给客户端的数据信息
5、Web服务器关闭TCP连接
一般情况下,一旦 Web 服务器向浏览器发送了请求的数据,它就要关闭 TCP 连接,关闭过程参考TCP 三次握手与四次挥手 中四次挥手过程,但是如果浏览器或者服务器在其头信息加入了这个请求头:Connection: keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
6、浏览器解析html代码
浏览器拿到HTML文件后,开始解析HTML代码,遇到静态资源时,就向服务器端去请求下载(此时又回发送新的请求)。
7、浏览器对页面进行渲染呈现给用户
浏览器利用自己内部的工作机制,把请求到的静态资源和HTML代码进行渲染,呈现给用户。
由于时间仓促,错误与疏忽之处在所难免,希望各位朋友们以邮件的形式反馈问题给我,再次表示感谢!
- 作者:xmlwch
- 原文链接:https://m730.xmlwch.cn/2021/08/12/network/a-complete-http-request.html
- 版权声明:本作品采用 知识共享 署名-相同方式共享 4.0 国际(CC BY-SA 4.0)许可协议 进行许可,转载无需与我联系,但请注明出处。