浏览器一个HTTP请求的过程

浏览器一个请求的过程

当我们在浏览器地址栏输入 www.xx.com ,然后回车, 这个请求背后经历了什么?以下是个人理解,如有偏差,请纠正!


首先重新温习下网络模型:
  • 七层结构(至顶向下):应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

这里写图片描述

client(浏览器) 与Server 通过HTTP协议通讯,HTTP协议属于”应用层协议”;HTTP基于TCP协议,TCP通过Socket进行通讯,TCP 被称为“传输层协议”。而HTTPS 还需要走会话层SSL\TLS等协议;传输层之下是网络层,这里主要是路由协议OSPF等进行路由选择,转发;再向下数据链路层主要是ARP、RARP协议完成IP和MAC地址互相解析,再向下是物理层主要是基于IEEE802.X等协议进行数据比特流转成高低电平的定义;

当浏览器发出请求时候,首先通过应用层DNS协议得到对应IP地址,在这经历全球路由大接力;而传输层TCP协议采用“三次握手”协议建立连接和“四次握手”协议断开连接,然后数据链路层解析IP与MAC地址的映射;数据经过层层数据封包、解包过程,如下:
这里写图片描述

这里特别强调下三次握手建立连接,放图作为参考:
这里写图片描述

Wireshark中抓包图,如下:
这里写图片描述

四次握手断开连接:
这里写图片描述

客户端发起 FIN ACK, 服务端应答 ACK, 待服务端数据发送完成后,发送FIN ACK, 客户端应答 ACK, 连接断开。
这里写图片描述

注: WireShark中“四次握手“的数据并不一定会在一起。


从应用服务角度分析

数据交换主要通过HTTP 协议, HTTP协议是无状态协议。多数通过GET、POST方法,GET与POST区别:
GET:请求获取指定的资源,不改变服务器状态,GET方法是幂等的,GET方法的报文主体没有任何语义。
POST: 根据请求报文主体对指定的资源做出处理,改变服务器状态,POST方法不幂等。

http方法不仅只有GET、POST, http1.1中含有如下方法:
这里写图片描述

RESTful API 就是利用这组方法来统一表述资源的状态转化。

同时,由于http无状态协议的特点,服务端需要记录用户时,就需要用某种机制来识具体的用户, 通常采用cookies、session。

session 本意是会话,是一个抽象概念。将 clinet 和 server 之间一对一的交互,抽象为“会话”,开发者为了实现一对一的“隔离”,中断和继续等操作,进而衍生出“会话状态”,也就是 session 的概念。

如何维护这个session概念,很自然的想到在http请求报文中加入登录标识就可以了,这个登录标识就是cookie。而 cookie 是一个实际存在的东西,http 协议中定义在 header 中的字段。这种技术的实现就是利用了cookie技术。 cookie是存储key-value对的一个文件,务必记住,它是由服务器将cookie添加到response里一并返回给客户端,然后客户端会自动把response里的cookie接收下来,并且保存到本地,下次发出请求的时候,就会把cookie附加在request里,服务器在根据request里的cookie遍历搜索是否有与之符合的信息。

cookie 虽然很方便,但是使用 cookie 有两个的弊端:

  1. cookie 中的所有数据在客户端就可以被修改。这就意味着数据非常容易被伪造,一些重要的数据就不能存放在 cookie 中;
  2. 如果 cookie 中数据字段太多会影响传输效率;

为了解决这些问题,就产生了 session,
session是一种服务器机制,使用Hash散列表结构来保存信息。
1. 每个 session 都对应一个 session_id,通过 session_id 可以查询到对应的 session;
2. session_id 通常是存放在客户端的 cookie 中,服务端存好 session 之后将对应的 session_id 设置在 cookie 中发送给客户端;
3. 当请求到来时,服务端检查 cookie 中保存的 session_id 并通过这个 session_id 与服务器端的 session 关联起来,进行数据的保存和修改;

这就是大多数人通常所说的session, 这里其实是指的 session实现。

server 端通常采用Nginx、Apache;

这里以PHP为例:
Nginx接收到请求,进行一些验证,如黑白名单拦截等, 是否有限流限制,是否有负载均衡设置;
如果请求的是静态内容,Nginx会将结果直接返回给用户。
如果请求的是动态内容,Nginx会将请求交给fastcgi客户端, 通过fastcgi_pass将这个请求发送给进程php-fpm。Nginx 不支持对外部动态程序的直接调用或者解析 ,所有的外部程序必须通过FastCGI接口来调用。

展开阅读全文

没有更多推荐了,返回首页