当我们在浏览器地址栏输入网址,到最后看到页面,中间都经历了什么?

1,559 阅读8分钟

当我们在地址栏输入网址后,会进行URL地址解析、DNS域名解析、和服务器TCP连接(三次握手)、把客户端信息传递给服务器(发送HTTP请求)、服务器得到并处理请求(HTTP响应内容)、客户端渲染服务器返回内容、与服务器断开TCP连接(四次挥手),这七个步骤。

下面我们来详细看一下每一步经历的内容

1. URL地址解析

URI/URL/URN

  • URI:Uniform Resource Identifier 统一资源标识服,URL和URN是URI的子集
  • URL:Uniform Resource Locator 统一资源定位服,根据这个地址能找到对应的资源
  • URN:Uniform Resource Name 统一资源名称,一般指国际上通用的(标准的)一些名字(例如:国际统一发版的编号)

一个完整的URL包含的内容

例如:www.baidu.com:80/index.html?…

  • 协议(http://)传输协议就是能够把客户端和服务器端通信的信息进行传输的工具(类似于快递小哥)
    • http:超文本传输协议,除了传递文本,还可以传递媒体资源文件(或者流文件)及xml格式数据
    • https:更加安全的http,一般涉及支付的网站都要采用https协议。(s:ssl 加密传输)
    • ftp:文件传输协议(一般应用于把本地资源上传到服务器端)
      • FileZilla:FTP上传工具,通过这个工具,通过FTP传输协议,我们可以把本地的文件上传到服务器上
  • 域名(www.baidu.com):一个让用户方便记忆的名字(不通过域名,我们也可以直接用服务器的外网IP也能访问到服务器,但是外网IP不好记)
    • 顶级域名(以腾讯为例:qq.com)
    • 一级域名(www.qq.com)
    • 二级域名(sports.qq.com)
    • 三级域名(kbs.sports.qq.com)
    • .com 国际域名
    • .cn 中文域名
    • .edu 教育
    • .....
  • 端口号(:80):端口号的取值范围0~65535,用端口号来区分同一台服务器上的不同项目
    • http默认端口号:80
    • https默认端口号:443
    • ftp默认端口号:21
    • 如果项目采用的就是默认端口号,我们在书写地址的时候,不用加端口号,浏览器在发送请求的时候会帮我们默认给加
  • 请求资源路径名称(index.html)
    • 默认的路径或者名称(xxx.com/不指定资源名,服务器会找默认的资源,一般默认的资源名是default.html、index.html...当然这些可以在服务器端自己配置)
    • 用户注意伪URL地址的处理(URL重写技术是为来增加SEO搜索引擎优化的,动态的网址一般不能被搜索引擎收录,所以我们要把动态网址静态化,此时需要的是重写URL)
  • 问号传参信息(?from=ch*x=1)目的就是信息传输
    • 客户端把信息传递给服务器,有很多方式
      • URL地址问号传参
      • 请求报文传输(请求头和请求主体)
  • HASH值(#hash)
    • 也能充当信息传输的方式
    • 锚点定位
    • 基于HASH实现路由管控(不同的HASH值,展示不同的组件和模块)

特殊字符加密和解密

请求的地址中,如果出现非有效unicode编码内容,现代版浏览器会默认的进行编码

  1. 可以基于encodeURI编码,我们也可以基于encodeURI解码,我们一般用encodeURI编码的是整个URL,这样整个URL中的特殊字符都会自动编译
  2. encodeURIComponent/decodeURIComponent,它相对于encodeURI来说,不用于给整个URL编码,而是给URL部分信息进行编码(一般都是问号传参的指编码)
    • 客户端和服务器端进行信息传播的时候,如果需要把请求的地址和信息编码,我们则基于以上两种方式处理,服务器端也存在这些方法,这样就可以统一编码解码了
  3. 客户端还存在一种方式,针对于中文的编码方式,escape/unescape,这种方式一般只应用与客户端页面之间自己的处理,例如:从列表跳转到详情,我们可以把传递的中文信息基于这个编码,详情页获取编码后的信息在解码,在比如我们在客户端中的cookie信息,如果信息是中文,我们也基于这种方法编码
    <buttom id='link'>按钮</button>
    <script>
        link.onclick=function(){
            //跳转页面
            window.location.href="https://www.baidu.com/";
            //从新的页面打开网址
            window.open('https://www.baidu.com');
        }
    </script>
    <script>
        //基于JS实现页面跳转
        let url = window.location.href;
		//=>跳转页面
		window.location.href = "https://www.baidu.com/?from=" + encodeURIComponent(url);
		window.open("https://www.baidu.com/");
    </script>

2. DNS域名解析

DNS服务器:域名解析服务器,在服务器上存储着 域名<=>服务器外网IP 的相关记录

而我们发送请求时候所谓的DNS解析,其实就是根据域名在DNS服务器上查找到对应服务器的外网IP

NDS优化

  1. DNS缓存(一般浏览器会在第一次解析后,默认建立缓存,时间很短,只有一分钟左右)
  2. 减少DNS解析次数(一个网站中我们需要发送请求的域名和服务器尽可能少即可)
  3. 进行DNS预获取(dns-prefetch):在页面加载开始的时候,就把当前页面中需要访问其他域名(服务器)的信息进行提前DNS解析,以后加载到具体内容部分可以不用解析了
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//static.360buyimg.com">
<link rel="dns-prefetch" href="//misc.360buyimg.com">
<link rel="dns-prefetch" href="//img10.360buyimg.com">
<link rel="dns-prefetch" href="//img11.360buyimg.com">
<link rel="dns-prefetch" href="//img12.360buyimg.com">
......

3. 和服务器TCP连接(三次握手)

TCP是个传输协议

  • 第一次握手:由浏览器发起,告诉服务器我要发送请求了
  • 第二次握手:由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧
  • 第三次握手:由浏览器发送,告诉服务器,我马上就发了,准备接受吧

![](建立TCP连接(三次握手)

4. 把客户端信息传递给服务器(发送HTTP请求)

请求报文:所有经过传输协议,客户端传递给服务器的内容,都被称为请求报文

  • 起始行
  • 请求头(首部)
  • 请求主体

响应报文:所有经过传输协议,服务器返回给客户端的内容,都被称为响应报文

  • HTTP响应状态码(常用的)
    • 200 / 201 / 204
    • 301 / 302 / 304 / 307
    • 400 / 401 / 404
    • 500 / 503
  • 响应头(首部)
  • 响应主体

HTTP报文:请求报文+响应报文

谷歌浏览器F12 =》network(所有客户端和服务器端的交互信息在这里都可以看到),点击某一条信息,在右侧可以看到所有的HTTP报文信息

5. 服务器得到并处理请求(HTTP响应内容)

一般服务器分为:WEB(图片)服务器和数据服务器

  • Tomcat、 Nginx、 Apache、 IIS ......

响应报文:所有经过传输协议,服务器返回给客户端的内容,都成为响应报文

  • 响应状态码
    • 200 OK:成功
    • 201 Created:成功(一般应用与告诉服务器创建一个新文件,最后服务器创建成功后返回状态码)
    • 204 No Content:对于某些请求(例如:PUT或者DELETE),服务器不想处理,可以返回空内容,并且用204状态码告知
    • 301 Moved Permanently 永久重定向(永久转移)
    • 302 Moved Temporarily 临时转移,很早以前基本上用302来做,但是现在主要用307来处理这个事情,
    • 304 Not Modified :设置HTTP的协商缓存
    • 307 意思就是临时重定向Moved Temporarily,主要用于:服务器的负载均衡等
    • 400 Bad Request:传递给服务器的参数错误
    • 401 Unauthorized: 无权限访问
    • 404 Not Found: 请求地址错误
    • 500 Internal Server Error: 未知服务器错误
    • 503 Service Unavailable: 服务器超负荷
  • 响应头(首部)
  • 响应主体

6. 客户端渲染服务器返回的内容

浏览器渲染页面的步骤

  • 解析HTML,生成DOM树,解析CSS,生成CSSOM树
  • 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  • Layout(回流): 根据生成的渲染树,计算它们在设备视口(viewport)内的确切位置和大小,这个阶段是回流
  • Painting(重绘): 根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  • Display:将像素发送给GPU,展示在页面上

7. 与服务器断开TCP连接(四次挥手)

  • 第一次挥手:由浏览器发起,发送给服务器,我请求报文发送完了,你准备关闭吧;
  • 第二次挥手:由服务器发起,告诉浏览器,我接收完请求报文,我准备关闭,你也准备吧;
  • 第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完毕,你准备关闭吧;
  • 第四次挥手:由浏览器发起,告诉服务器,我响应报文接收完毕,我准备关闭,你也准备吧

![](断开连接(四次挥手).png