当我们在浏览器的地址栏输入 www.xmlwch.cn ,然后回车,回车这一瞬间到看到页面到底发生了什么呢?

个人理解至少需要经历以下步骤:

  1. 域名解析
  2. 建立TCP连接
  3. 浏览器向Web服务器发送请求命令
  4. Web服务器应答
  5. Web服务器关闭TCP连接
  6. 浏览器解析html代码
  7. 浏览器对页面进行渲染呈现给用户

1、域名解析

客户端根据访问的域名找到其IP地址。DNS查找过程如下:

  1. 浏览器缓存:首先搜索浏览器自身的DNS缓存(缓存的时间比较短,大概只有1分钟,且只能容纳1000条缓存),看自身的缓存中是否是有域名对应的条目,而且没有过期,如果有且没有过期则解析到此结束。
  2. 系统缓存:如果浏览器自身的缓存里面没有找到对应的条目,那么浏览器会搜索操作系统自身的DNS缓存,如果找到且没有过期则停止搜索解析到此结束。
  3. 路由器缓存:如果系统缓存也没有找到,则会向路由器发送查询请求。
  4. 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。

详细参考四种常见的 POST 提交数据方式

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代码进行渲染,呈现给用户。

由于时间仓促,错误与疏忽之处在所难免,希望各位朋友们以邮件的形式反馈问题给我,再次表示感谢!