文章目录
- 1. 输入URL
- 2. 客户端查看浏览器缓存文件
- 3. 获取服务器IP地址
- 4. 组装HTTP(GET)请求报文
- 5. 客户端建立TCP连接,与服务器端进行三次握手
- 6. 建立连接后发送HTTP请求
- 7. 服务器预处理
- 7.1 服务器(IIS、apache等)接收并解析,将请求转发到服务程序(ASP.NET、PHP、Ruby等)。
- 7.2 将URL将映射到文件
- 7.3 服务器检查请求头是否有缓存信息
- 7.4准备HTTP响应,有数据库的操作数据库 。
- 8. 服务器响应报文并通过建立的TCP返回到客户端
- 9. 客户端接收HTTP请求,关闭TCP连接(四次挥手)或者保留重用
- 10. 客户端预处理响应
- 11. 解析HTML文档
- 12. 显示页面
1. 输入URL
这里举例facebook.com
2. 客户端查看浏览器缓存文件
如果存在缓存文件并且缓存文件是最新可用的则直接跳至客户端解码步骤()
3. 获取服务器IP地址
通常按照以下顺序获取IP地址
- 浏览器缓存 -浏览器缓存DNS记录一段时间。有趣的是,操作系统不会告诉浏览器每个DNS记录的生存时间,因此浏览器将它们缓存一段固定的时间(因浏览器而异,2到30分钟)。
- 操作系统缓存 - 操作系统有自己的缓存(host文件)。如果浏览器缓存不包含所需的记录,则浏览器进行系统调用(Windows中的gethostbyname)。
- 路由器缓存 - 请求继续到您的路由器,路由器通常有自己的DNS缓存。
- ISP DNS缓存 - 检查的下一个位置是缓存ISP的DNS服务器。有了缓存,自然而然。
- 递归搜索 - 您的ISP的DNS服务器开始递归搜索,从根名称服务器,通过.com顶级域名服务器,到Facebook的名称服务器。通常,DNS服务器将在缓存中具有.com名称服务器的名称,因此不需要命中根名称服务器。
4. 组装HTTP(GET)请求报文
这里只是组装请求报文,并不发送
HTTP请求由3个部分构成,分别是:
请求方法URI协议/版本
请求头(Request Header)
正文
5. 客户端建立TCP连接,与服务器端进行三次握手
- 第一次握手:客户端A将标志位SYN(同步序列编号 Synchronize Sequence Numbers)置为1,随机产生一个值为seq(序号)=J(J的取值范围为=1~7)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认。
- 第二次握手:服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK (确认字符Acknowledgement)都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_RCVD状态。
- 第三次握手:客户端A收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务端B,服务端B检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态,完成三次握手,随后客户端A与服务端B之间可以开始传输数据了。
6. 建立连接后发送HTTP请求
通过TCP连接发送已经组装好的HTTP请求
7. 服务器预处理
7.1 服务器(IIS、apache等)接收并解析,将请求转发到服务程序(ASP.NET、PHP、Ruby等)。
7.2 将URL将映射到文件
例如:facebook.com/user/YooHoeh.php
映射为httpdocs/facebook/user/YooHoeh.php
7.3 服务器检查请求头是否有缓存信息
有就返回304之类的状态码。
7.4准备HTTP响应,有数据库的操作数据库 。
8. 服务器响应报文并通过建立的TCP返回到客户端
HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成,分别是:
状态行
响应头(Response Header)
响应正文
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
<head>
<title>http</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>
状态行:
状态行由协议版本、数字形式的状态代码、及相应的状态描述,各元素之间以空格分隔。
格式: HTTP-Version Status-Code Reason-Phrase CRLF
例如: HTTP/1.1 200 OK
– 协议版本:是用http1.0还是其他版本
– 状态描述:状态描述给出了关于状态代码的简短的文字描述。比如状态代码为200时的描述为 ok
– 状态代码:状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。更多参考10.2 浏览器检查响应状态代码
9. 客户端接收HTTP请求,关闭TCP连接(四次挥手)或者保留重用
- 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
- 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
- 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
- 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
10. 客户端预处理响应
10.1 检查状态码 有缓存资源 进行缓存
10.2 浏览器检查响应状态代码
3xx结果状态代码,授权请求(401),错误(4xx和5xx)等; 这些处理方式与正常答案不同(2xx)
状态码 | 含义 |
---|---|
1xx | 信息性状态码,表示服务器已接收了客户端请求,客户端可继续发送请求。 |
100 | Continue |
101 | Switching Protocols |
2xx | 成功状态码,表示服务器已成功接收到请求并进行处理。 |
200 | OK 表示客户端请求成功 |
204 | No Content 成功,但不返回任何实体的主体部分 |
206 | Partial Content 成功执行了一个范围(Range)请求 |
3xx | 重定向状态码,表示服务器要求客户端重定向。 |
301 | Moved Permanently 永久性重定向,响应报文的Location首部应该有该资源的新URL |
302 | Found 临时性重定向,响应报文的Location首部给出的URL用来临时定位资源 |
303 | See Other 请求的资源存在着另一个URI,客户端应使用GET方法定向获取请求的资源 |
304 | Not Modified 服务器内容没有更新,可以直接读取浏览器缓存 |
307 | Temporary Redirect 临时重定向。与302 Found含义一样。302禁止POST变换为GET,但实际使用时并不一定,307则更多浏览器可能会遵循这一标准,但也依赖于浏览器具体实现 |
4xx | 客户端错误状态码,表示客户端的请求有非法内容。 |
400 | Bad Request 表示客户端请求有语法错误,不能被服务器所理解 |
401 | Unauthonzed 表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用 |
403 | Forbidden 表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因 |
404 | Not Found 请求的资源不存在,例如,输入了错误的URL |
5xx | 服务器错误状态码,表示服务器未能正常处理客户端的请求而出现意外错误。 |
500 | Internel Server Error 表示服务器发生不可预期的错误,导致无法完成客户端的请求 |
503 | Service Unavailable 表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常 |
10.3. 对状态码进行解码(比如gzip压缩等)
10.4. 对资源类型决定如何处理(暂定为HTML文档)
将Content-Type设置为text / html的标头。指示浏览器将响应内容呈现为HTML,而不是将其作为文件下载。浏览器将使用标头来决定如何解释响应,但也会考虑其他因素,例如URL的扩展名。
11. 解析HTML文档
不同浏览器可能解析的过程不太一样,这里我们只介绍webkit的渲染过程
11.1 构建DOM Tree
11.2 构建CSS Rules解析过程中遇到相关资源等进行下载
- css样式表为异步加载,不会停止后面的解析
- js为默认为同步加载,会等待js文件下载完毕后继续后面的解析,可以通过添加
defer/asyc
修改这个过程。 - img/video为异步加载,不会停止后面的解析
11.3 构建渲染
浏览器将DOM Tree 和 CSS Rules 构建成Render Tree,脚本(js)对相关DOM进行操作。
12. 显示页面
如果英语阅读能力可以推荐参考 http://igoro.com/archive/what-really-happens-when-you-navigate-to-a-url ,这篇博客写的很详细。
参考链接:
https://blog.csdn.net/wlk2064819994/article/details/79756669
https://github.com/jirengu/frontend-interview/issues/5