浏览器访问URL完整流程(ThinkPHP+Nginx部署架构)

71 阅读9分钟

浏览器访问URL完整流程(ThinkPHP+Nginx部署架构)

本文档详细梳理了用户在浏览器输入URL后,从请求发起至页面最终渲染的全链路流程,重点拆解服务器端Nginx、PHP-FPM与ThinkPHP框架的协同处理逻辑,适配ThinkPHP开发者面试学习与日常技术梳理需求。

一、整体流程框架

浏览器访问URL的完整流程可划分为6大核心阶段,各阶段环环相扣,最终实现页面资源的请求与渲染:

  1. 浏览器本地预处理

  2. DNS解析(域名→IP地址)

  3. 建立网络连接(TCP握手+HTTPS加密)

  4. 服务器端处理(Nginx→PHP-FPM→ThinkPHP)

  5. 断开网络连接(TCP四次挥手)

  6. 浏览器接收响应并渲染页面

二、各阶段详细说明

阶段1:浏览器本地预处理

用户在浏览器输入URL并回车后,浏览器首先完成本地校验与缓存查询,避免无效网络请求:

  1. URL合法性校验:判断输入内容是URL地址(如www.xxx.com)还是搜索关键词(如“ThinkPHP教程”)。若是URL则进入后续流程;若是搜索关键词则直接跳转到默认搜索引擎(如百度、谷歌)。

  2. 本地缓存查询:优先从本地缓存获取资源,提升访问效率:

    • DNS缓存:查询浏览器本地保存的域名-IP映射关系(有过期时间),若存在则直接使用对应IP;

    • 页面资源缓存:查询是否存在已缓存的页面资源(如.html、.css、.js文件),若资源设置了强缓存(Cache-Control: max-age / Expires)且未过期,则直接从本地加载资源,无需发起网络请求;

    • 若缓存未命中或已过期,进入网络请求阶段。

阶段2:DNS解析(域名→IP地址)

浏览器无法直接通过域名访问服务器,需通过DNS(域名系统)将域名转换为服务器的公网IP地址,流程如下:

  1. 查询本地hosts文件:优先读取系统hosts文件(Windows路径:C:\Windows\System32\drivers\etc\hosts;Linux/Mac路径:/etc/hosts),若文件中存在该域名的IP映射,则直接使用该IP;

  2. 查询本地DNS服务器:若hosts文件无对应记录,向本地DNS服务器(通常是路由器或运营商DNS,如电信114.114.114.114)发送DNS查询请求;

  3. 层级查询权威DNS:本地DNS服务器若无缓存,则依次向根DNS服务器→顶级域名DNS服务器(如.com、.cn服务器)→权威DNS服务器(域名注册商提供的解析服务器)发起查询,最终获取服务器IP地址及默认端口(HTTP默认80端口,HTTPS默认443端口)。

阶段3:建立网络连接

获取服务器IP和端口后,浏览器与服务器建立可靠的网络连接,分为HTTP和HTTPS两种场景:

3.1 HTTP协议(明文传输)

通过TCP三次握手建立连接,确保数据可靠传输:

  1. 第一次握手:浏览器向服务器发送同步报文(SYN),请求建立连接;

  2. 第二次握手:服务器接收后,返回同步+确认报文(SYN+ACK),确认收到请求并同意建立连接;

  3. 第三次握手:浏览器接收后,返回确认报文(ACK),连接建立完成,可开始传输数据。

3.2 HTTPS协议(加密传输,主流)

在TCP三次握手基础上,额外增加TLS握手(TLS是SSL的升级版),实现数据加密:

  1. 浏览器向服务器发送TLS版本、加密套件列表;

  2. 服务器返回选中的加密套件、服务器证书(含公钥);

  3. 浏览器验证证书有效性(由CA机构颁发,防止伪造),验证通过后生成随机会话密钥,用服务器公钥加密后发送给服务器;

  4. 服务器用自身私钥解密,获取会话密钥,后续双方通过该会话密钥进行对称加密传输(对称加密效率更高)。

阶段4:服务器端处理(核心环节)

此阶段是面试重点考察内容,基于ThinkPHP主流部署架构(Nginx+PHP-FPM),实现动态请求的分层处理:

4.1 Nginx的职责(Web服务器/反向代理)

Nginx监听80/443端口,首先接收浏览器发送的HTTP/HTTPS请求报文(含请求行、请求头、请求体),核心操作如下:

  1. 静态资源直接返回:若请求的是静态资源(.jpg、.css、.js、.html等),Nginx直接从服务器本地磁盘读取文件,经gzip压缩(可选)后返回给浏览器,无需经过PHP-FPM和ThinkPHP;

  2. 动态请求转发:若请求的是动态资源(如index.php、ThinkPHP路由地址/index/index/index),Nginx根据nginx.conf配置,通过FastCGI协议将请求转发给PHP-FPM(默认监听9000端口);

  3. 额外功能:请求过滤(拦截非法请求)、负载均衡(多台PHP服务器时分发请求)、虚拟主机配置(一个服务器部署多个网站)等。

4.2 PHP-FPM的职责(PHP进程管理器)

PHP-FPM负责管理PHP运行进程,接收并处理Nginx转发的请求:

  1. 接收FastCGI请求:接收Nginx通过FastCGI协议转发的请求参数(如URL、POST数据);

  2. 进程管理:从进程池中复用/创建PHP工作进程,将请求参数传递给该进程;

  3. 初始化PHP环境:PHP进程加载PHP核心扩展,执行ThinkPHP的唯一入口文件(项目根目录public/index.php)。

4.3 ThinkPHP框架的内部流程

从入口文件开始,ThinkPHP按固定顺序完成动态业务处理:

  1. 框架初始化:执行public/index.php,加载ThinkPHP核心文件(think.php),初始化应用容器、全局配置(config/目录)、自动加载机制(Composer+框架类加载),创建应用实例;

  2. URL路由解析:根据路由规则(route/app.php定义或默认规则「模块/控制器/方法」),解析URL地址,提取模块名、控制器名、操作方法名及URL参数(如/user/detail/id/1中的id=1);路由匹配失败则返回404错误;

  3. 中间件执行(前置):按顺序执行全局中间件(app/middleware.php)、应用中间件、控制器中间件,完成通用业务处理(如跨域CORS、登录验证、日志记录、CSRF防护);若中间件判断请求不合法(如未登录访问权限接口),则直接中断流程并返回响应(如401未授权);

  4. 控制器业务处理:实例化对应控制器类(如app/index/controller/Index.php),调用指定操作方法(如index方法);在方法中完成具体业务逻辑:调用模型(app/index/model/)操作数据库(连接MySQL、执行CRUD、关闭连接)、调用第三方接口、处理请求参数等;

  5. 响应数据处理:控制器返回数据(JSON或视图模板名),框架加载对应模板文件(app/index/view/)进行渲染,生成最终HTML;执行中间件后置操作(清理临时资源、记录响应日志);

  6. 框架收尾:释放应用资源、关闭数据库连接、记录运行日志。

4.4 响应返回流程

ThinkPHP将处理后的响应数据(HTML/JSON)返回给PHP-FPM,PHP-FPM通过FastCGI协议回传给Nginx,Nginx添加响应头(如Content-Type)后,将响应报文返回给浏览器。

阶段5:断开网络连接

数据传输完成后,根据连接类型决定是否断开TCP连接:

  1. 短连接(HTTP/1.0默认,或HTTP/1.1设置Connection: close):执行TCP四次挥手断开连接:

    • 浏览器发送终止报文(FIN),表示不再发送数据;

    • 服务器返回确认报文(ACK),并继续发送剩余数据;

    • 服务器发送终止报文(FIN),表示数据发送完毕;

    • 浏览器返回确认报文(ACK),连接断开。

  2. 长连接(HTTP/1.1默认Connection: keep-alive):连接不立即断开,可复用该连接发送后续请求,减少握手开销,直至超时或双方主动关闭。

阶段6:浏览器接收响应并渲染页面

浏览器接收Nginx返回的响应数据后,完成页面解析与渲染:

  1. 解析响应数据:解析响应头(通过Content-Type判断数据类型,如text/htmlapplication/json),提取响应体;

  2. 页面渲染(针对HTML):

    • 解析HTML,生成DOM树(文档对象模型,描述页面结构);

    • 解析CSS,生成CSSOM树(CSS对象模型,描述样式规则);

    • 合成渲染树:结合DOM树与CSSOM树,仅包含需要显示的节点及样式;

    • 布局(Layout):计算渲染树节点的位置、大小(宽高、边距);

    • 绘制(Paint):根据布局结果,将节点绘制到屏幕(文字、图片、颜色等);

    • 合成(Composite,可选):将页面分为多个图层(如视频、文字图层),分别绘制后合并,提升渲染效率。

  3. 加载额外资源:渲染过程中,若HTML引用外部资源(CSS、JS、图片、字体),浏览器发起新请求(复用长连接)加载资源;其中JS脚本默认阻塞DOM渲染,可通过defer/async属性优化;

  4. 页面交互:渲染完成后,浏览器通过JS监听用户操作(点击、输入),处理交互逻辑(如AJAX请求、修改DOM)。

三、面试作答精简版

面试时可按以下逻辑简洁作答,兼顾完整性与重点:

  浏览器访问URL的完整流程分为6步:

  1.  浏览器本地校验URL,查询DNS和页面缓存,缓存命中直接渲染,未命中进入下一步;

  2.  通过DNS解析将域名转换为服务器IP;

  3.  建立网络连接:HTTP走TCP三次握手,HTTPS额外加TLS握手加密;

  4.  服务器端处理:Nginx接收请求,静态资源直接返回,动态请求通过FastCGI转发给PHP-FPM;PHP-FPM启动PHP进程,执行ThinkPHP入口文件,框架依次完成初始化→路由解析→中间件处理→控制器业务处理(调用模型操作数据库)→响应渲染,结果回传给Nginx;

  5.  Nginx将响应返回给浏览器,按需断开TCP连接;

  6.  浏览器解析HTML/CSS/JS,构建DOM树和渲染树,布局绘制后呈现页面,同时加载额外静态资源。

四、核心总结

  1. 全流程核心是“分层处理”:浏览器负责请求发起与渲染,DNS负责域名解析,Nginx负责请求分发与静态资源返回,PHP-FPM负责PHP进程管理,ThinkPHP负责动态业务逻辑;

  2. 服务器端是面试重点:需明确Nginx与PHP-FPM的通信协议(FastCGI)、ThinkPHP的入口文件与内部执行顺序;

  3. HTTPS的核心是TLS握手:通过证书验证和对称加密实现数据安全传输;

  4. 缓存与长连接是性能优化的关键:减少重复请求和连接建立开销。