从输入URL到页面加载发生了什么?

一、前言

文章为了加深自我理解,参考:
前端经典面试题: 从输入URL到页面加载发生了什么?
老生常谈-从输入url到页面展示到底发生了什么
HTTP 请求头与请求体
四种常见的POST提交方式

二、开始

从用户开始输入 url 到用户见到页面内容,过程如下:

  1. 输入 url
  2. 查找 ip ,从本地系统查找 hosts 文件,是否有 ip ? 有则下一步 : 没有,进行 DNS 解析
  3. TCP 连接
  4. 发送 HTTP 请求
  5. 服务器处理并返回 HTTP 请求
  6. 浏览器解析渲染页面
  7. 用户看到完整页面

三、具体过程

I. 输入 url

用户在浏览器中输入网址的时候,浏览器就只能的会从历史记录、书签来搜索你当前输入的地址,如果你访问的是有缓存过的地址,网页可能直接展示出来。

II. 查找 ip

每个域名都是对应有一个 ip 地址, 诸如 www.baidu.com 这些名称只是用来方便用户记忆。所以在获取网页内容之前,浏览器得先知道这个网址的 ip 地址,才能去到对应的服务器去获取资源。
首先,浏览器会尝试在本地的 hosts 文件中去查看是否有相应的 ip 记录,有的话就直接用对应的 ip ,省去 DNS 解析。

DNS 解析

DNS (Domain Name System ,域名系统)解析,就是一个网址到 ip 地址转换的过程,解析是一个递归查询的过程。

DNS解析

经过多次的服务器往返后,得到了对应的 ip 地址。从上述过程中,可以看出网址的解析是一个从右向左的过程,浏览器首先会去访问本地DNS服务器,查看是否有缓存 ip ,没有,那么去访问 根服务器,每个网址的真正地址是www.baidu.com.,就是在网址后还有一个点,这个点就是指向根服务器,然后根服务器告诉你,你应该去问COM顶级域名服务器,然后COM顶级域名服务器又告诉你,你应该去问baidu.com服务器,这下终于找到负责人了,baidu.com服务器就会把它管理的www.baidu.com的 ip 地址返回告诉浏览器,费了这么大劲,浏览器终于如愿以偿拿到 ip 了,接下来就可以向该 ip 拿页面了。
问题是,如果每一次浏览器访问个网站都要这么费劲,那用户体验不就很差?所以聪明的浏览器在访问过一次之后,会去缓存下这个网址对应的 ip 地址,下次就能直接用了。另外,聪明的本地DNS服务器、所有的服务器也会存下映射关系,以便下次使用。另外,也可以人为修改 Hosts 文件来指定网址的 ip 映射关系。

III. 建立 TCP 连接

浏览器在拿到 ip 地址之后,就开始准备 HTTP 请求了,但首先要先和服务器建立连接通道,这时候就用到 TCP 建立三次握手了。 TCP 协议是用来建立对话通道的,在客户端和服务器还没对接之前,是无法确定各种各样的请求的,举个网络上看到的例子:

  1. 甲: “喂!是乙吗?”
  2. 乙: “是呀,我是乙。”
  3. 甲: “那我们开始对话吧!”

只有确保的请求服务器正确,才可以真正开始请求。另外,在请求头会有一个Connection: keep-alive,表示保持 TCP 连接,这样客户端在下次请求的时候,就不需要重新建立 TCP 连接了,虽然这样会损耗部分服务器性能,但对双方(客户端、服务器)也都是有好处的。

IV. 发起 HTTP 请求

典型的 HTTP 请求消息头域,如下:

  POST/GET http://download.microtool.de:80/somedata.exe 
  Host: download.microtool.de 
  Accept:*/* 
  Pragma: no-cache 
  Cache-Control: no-cache 
  Referer: http://download.microtool.de/ 
  User-Agent:Mozilla/4.04[en](Win95;I;Nav) 
  Range:bytes=554554- 

总的来说 HTTP 请求包含三部分:请求行、请求头、请求体(请求正文)。

a. 请求行

请求行分为三部分:请求方法、请求地址和协及版本。
HTTP/1.1定义的请求方法有 8 种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE,最常用的两种 GET 和 POST。以下为 GET 和 POST 区别的文章:
GET VS POST
注意: 在 POST、PUT、PATCH 三个请求中会包含请求体,其他的并没有。

b. 请求头

请求头的详细类型和内容的详细内容谷歌搜索,一下是一次请求的样例:

百度的 HTTP 请求

c. 请求体

请求体主要是用来存放数据,数据类型存储在 Content-Type 响应头上,接触过的有:

  1. application/x-www-form-urlencoded
    最常见的 POST 提交数据方式,浏览器原生<form>表单,格式如下
POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
  1. application/json
    主要用来提交 JSON 格式的数据,格式为:
POST http://www.example.com HTTP/1.1 
Content-Type: application/json;charset=utf-8

{"title":"test","sub":[1,2,3]}
  1. multipart/form-data
    使用表单上传文件时的格式,用于上传文件,格式如:
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
  1. text/xml
    传输数据,没用过,不清楚,格式如下:
POST http://www.example.com HTTP/1.1 
Content-Type: text/xml

<?xml version="1.0"?>
<methodCall>
    <methodName>examples.getStateName</methodName>
    <params>
        <param>
            <value><i4>41</i4></value>
        </param>
    </params>
</methodCall>

V. 服务器处理请求并返回 HTTP 报文

HTTP 请求也是三部分请求:状态码、相应头、响应体(响应报文)。

a. 状态码

状态码由3位数组成,第一个数字定义了相应类别,共有五种可能取值:

  • 1XX 消息:代表请求已被接受,需要继续处理。这类响应是临时响应,通常情况下,服务器是不会给客户端发送1xx响应。
  • 2XX 成功:代表请求成功被服务器接收、理解、接受。
  • 3XX 重定向:代表客户端需要采取进一步的操作才能完成请求。
  • 4XX 客户端错误:代表客户端看起来发生了错误,妨碍了服务器的处理。
  • 5XX 服务器错误:表示服务器无法完成明显有效的请求。
    参考: HTTP 状态码

b. 响应头

涉及到服务器名称、缓存、响应体类型等,详细内容自行谷歌。

c. 响应体

响应体除了有 JSON 数据等一些其他数据类型外,也是获取 HTML、CSS、JS、图片等文件的地方。

HTTP 和 HTTPS

HTTPS 是 HTTP 请求前,客户端与服务器先进行一次握手(TLS/SSL握手),用于数据加密,具体加密我不懂,参考这里:图解SSL/TLS协议。很明显的是,虽然 HTTPS 更为安全,但与 HTTP 相比,多了一次连接,肯定会影响一部分的加载速度。一张图说明:

HTTP 与 HTTPS

VI. 浏览器解析渲染页面

浏览器解析服务器返回的 HTML 时,是从上往下顺序解析的,遇到 CSS link、JS link 就会向服务器请求该资源,浏览器也开始生成 DOM 结构,但需要注意的是,CSS 文件不会阻塞 DOM 结构的生成,而 JS 文件会(因为 JS 可以操作 DOM),所以如果在 HTML 头部开始解析 JS 的话,浏览器会等 JS 请求完并且初始化结束才会继续生成 DOM 结构。这也是为什么 JS 经常放在 <body>最后,而且用的是window.onload=function(){}。不过可以在<script async></script>加个async,告诉浏览器不用等我 JS 啦,赶紧开始生成你的 DOM 树结构(async是异步加载的意思)。
DOM 树生成后,就要上色,这时候就是 CSS 的作用了。一张图说明:

浏览器解析渲染页面

另外,这里有个视频很好的讲解了浏览器对网页的处理:网站性能优化(中/英)

VII. 用户看到完整页面

到此,用户终于能完整的看到一个页面了,没想到吧,在这么短短2秒,浏览器做了这么多事,还跑了这么远,不容易。要学的内容还很多,这是一篇前端新手的理解,参考很多东西,如有出错,请严厉指出~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容