首先提出一个问题:从输入URL到页面加载发生了什么?
仔细思考这个问题,发现确实很深,这个过程涉及到的东西很多。这个问题的回答真的能够很好的考验一个人对知识了解的水平。而且从不同角度/专业看,回答的结果也会不一样。
从网络的角度回答,简略回答如下:
1.DNS域名解析;
2.建立TCP连接;
3.发送HTTP请求;
4.服务器处理请求;
5.返回响应结果;
6.浏览器解析HTML,布局渲染;
7.关闭TCP连接;
计算机网络概述
ISO与TCP/IP
需要了解的知识
ISO
TCP
IP
TCP/IP
UDP
在网络体系结构中,包含了众多的网络协议,这篇文章主要围绕 HTTP 协议(HTTP/1.1版本)展开。
互联网的关键技术就是TCP/IP协议。两台计算机之间的通信是通过TCP/IP协议在因特网上进行的。实际上这个是两个协议:
TCP : Transmission Control Protocol 传输控制协议
IP: Internet Protocol 网际协议。
IP:计算机之间的通信
IP协议是计算机用来相互识别的通信的一种机制,每台计算机都有一个IP.用来在internet上标识这台计算机。 IP 负责在因特网上发送和接收数据包。通过 IP,消息(或者其他数据)被分割为小的独立的包,并通过因特网在计算机之间传送。IP 负责将每个包路由至它的目的地。
IP协议仅仅是允许计算机相互发消息,但它并不检查消息是否以发送的次序到达而且没有损坏(只检查关键的头数据)。为了提供消息检验功能,直接在IP协议上设计了传输控制协议TCP.
TCP : 应用程序之间的通信
TCP确保数据包以正确的次序到达,并且尝试确认数据包的内容没有改变。TCP在IP地址之上引端口(port),它允许计算机通过网络提供各种服务。一些端口号为不同的服务保留,而且这些端口号是众所周知。
服务或者守护进程:在提供服务的机器上,有程序监听特定端口上的通信流。例如大多数电子邮件通信流出现在端口25上,用于wwww的HTTP通信流出现在80端口上。
当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信,占用两个计算机之间整个的通信线路。TCP 用于从应用程序到网络的数据传输控制。TCP 负责在数据传送之前将它们分割为 IP 包,然后在它们到达的时候将它们重组。
TCP/IP 就是TCP 和 IP 两个协议在一起协同工作,有上下层次的关系。
TCP 负责应用软件(比如你的浏览器)和网络软件之间的通信。IP 负责计算机之间的通信。TCP 负责将数据分割并装入 IP 包,IP 负责将包发送至接受者,传输过程要经IP路由器负责根据通信量、网络中的错误或者其他参数来进行正确地寻址,然后在它们到达的时候重新组合它们。
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
HTTP是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。在Internet上的Web服务器上存放的都是超文本信息,客户机需要通过HTTP协议传输所要访问的超文本信息。HTTP包含命令和传输信息,不仅可用于Web访问,也可以用于其他因特网/内联网应用系统之间的通信,从而实现各类应用资源超媒体访问的集成。
我们在浏览器的地址栏里输入的网站地址叫做URL (Uniform Resource Locator,统一资源定位符)。就像每家每户都有一个门牌地址一样,每个网页也都有一个Internet地址。当你在浏览器的地址框中输入一个URL或是单击一个超级链接时,URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来,并翻译成对应的网页。
HTTP 工作过程
就像刚才问的 从输入URL到页面加载发生了什么,其中工作的过程有以下几部分:
一次HTTP操作称为一个事务,其工作整个过程如下:
1、地址解析,
如用客户端浏览器请求这个页面:http://www.baidu.com/index.html
从中分解出协议名、主机名、端口、对象路径等部分,对于我们的这个地址,解析得到的结果如下:
协议名:http
主机名:www.baidu.com 被解析成 220.181.38.150
端口:80
对象路径:/index.html
在这一步,需要域名系统DNS解析域名www.baidu.com,得主机的IP地址。
2、封装HTTP请求数据包
把以上部分结合本机自己的信息,封装成一个HTTP请求数据包
3、封装成TCP包,建立TCP连接(TCP的三次握手)
在HTTP工作开始之前,客户机(Web浏览器)首先要通过网络与服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。
4、客户机发送请求命令
建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容。
5、服务器响应
服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
实体消息是服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
6、服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码
Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
HTTP 协议基础
HTTP是一个无状态的协议
HTTP是一个无状态的协议。无状态是指客户机(Web浏览器)和服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后服务器返回响应(response),连接就被关闭了,在服务器端不保留连接的有关信息.HTTP遵循请求(Request)/应答(Response)模型。客户机(浏览器)向服务器发送请求,服务器处理请求并返回适当的应答。所有HTTP连接都被构造成一套请求和应答。
这么做为了更快地处理大量事务,确保协议的可伸缩性
使用 Cookie 的状态管理
Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
请求 URI 定位资源
HTTP 协议使用 URI 定位互联网上的资源。正是因为 URI 的特定功能,在互联网上任意位置的资源都能访问到。
告知服务器意图的 HTTP 方法(HTTP/1.1)
持久连接
HTTP 协议的初始版本中,每进行一个 HTTP 通信都要断开一次 TCP 连接。比如使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无畏的 TCP 连接建立和断开,增加通信量的开销。
为了解决上述 TCP 连接的问题,HTTP/1.1 和部分 HTTP/1.0 想出了持久连接的方法。其特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。旨在建立一次 TCP 连接后进行多次请求和响应的交互。在 HTTP/1.1 中,所有的连接默认都是持久连接。
谷歌浏览器默认最多打开6个TCP连接
管线化
持久连接使得多数请求以管线化方式发送成为可能。以前发送请求后需等待并接收到响应,才能发送下一个请求。管线化技术出现后,不用等待亦可发送下一个请求。这样就能做到同时并行发送多个请求,而不需要一个接一个地等待响应了。
比如,当请求一个包含多张图片的 HTML 页面时,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术要比持久连接速度更快。请求数越多,时间差就越明显。
HTTP 协议报文结构
HTTP报文
用于 HTTP 协议交互的信息被称为 HTTP 报文。
HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。
HTTP有两类报文:请求报文和响应报文。
HTTP请求报文格式
HTTP请求报文主要由请求行、请求头部、请求正文3部分组成。
<request-line>
<headers>
<blank line>
[<request-body>]
请求行
请求航由3部分组成,请求方法、URL以及协议版本,之间由空格分隔。
请求方法包括GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE以及扩展方法,当然并不是所有的服务器都实现了所有的方法,部分方法即便支持,处于安全性的考虑也是不可用的
协议版本的格式为:HTTP/主版本号.次版本号,常用的有HTTP/1.0和HTTP/1.1
请求头部
请求头部为请求报文添加了一些附加信息,由“键/值”对组成,每行一对,名和值之间使用冒号分隔。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Cookie: BAIDUID=xx:FG=1; PSTM=1562221918; BIDUPSID=xxx; BD_UPN=xxx; BDUSS=xxx; H_PS_PSSID=xxx; BDORZ=xx; delPer=0; BD_CK_SAM=1; locale=zh; BD_HOME=1; BDRCVFR[S4-dAuiWMmn]=xx; PSINO=7; BDRCVFR[feWj1Vr5u3D]=xx; pgv_pvi=xx; pgv_si=xx; yjs_js_security_passport=xx; COOKIE_SESSION=xx; H_PS_645EC=xx; BDSFRCVID=xx; H_BDCLCKID_SF=xx; sugstore=1
Host: www.baidu.com
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
key |
value |
Host |
接受请求的服务器地址,可以是IP:端口号,也可以是域名 |
User-Agent |
发送请求的应用程序名称 |
Connection |
指定与连接相关的属性,如Connection:Keep-Alive |
Accept-Charset |
通知服务端可以发送的编码格式 |
Accept-Encoding |
通知服务端可以发送的数据压缩格式 |
Accept-Language |
通知服务端可以发送的语言 |
请求头部的最后会有一个空行,表示请求头部结束,接下来为请求正文,这一行非常重要,必不可少。
请求正文
可选部分,比如GET请求就没有请求正文
HTTP响应报文格式
HTTP响应报文主要由状态行、响应头部、响应正文3部分组成。
<status-line>
<headers>
<blank line>
[<response-body>]
状态行
状态行由3部分组成,分别为:协议版本、状态码、状态码描述,之间由空格分隔
HTTP/1.1 200 OK
协议版本:HTTP/1.1
状态码:200
状态码描述:OK
协议版本
状态码
状态代码为3位数字,200299的状态码表示成功,300399的状态码指资源重定向,400499的状态码指客户端请求出错,500599的状态码指服务端出错(HTTP/1.1向协议中引入了信息性状态码,范围为100~199)
1XX:信息提示。表示请求已被服务器接受,但需要继续处理,范围为100101。
2XX:请求成功。服务器成功处理了请求。范围为200206。
3XX:客户端重定向。重定向状态码用于告诉客户端浏览器,它们访问的资源已被移动,并告诉客户端新的资源位置。客户端收到重定向会重新对新资源发起请求。范围为300305。
4XX:客户端信息错误。客户端可能发送了服务器无法处理的东西,比如请求的格式错误,或者请求了一个不存在的资源。范围为400415。
5XX:服务器出错。客户端发送了有效的请求,但是服务器自身出现错误,比如Web程序运行出错。范围是500~505。
状态码描述
HTTP响应头部
响应头 |
说明 |
Server |
服务器应用程序软件的名称和版本 |
Content-Type |
响应正文的类型(是图片还是二进制字符串) |
Content-Length |
响应正文长度 |
Content-Charset |
响应正文使用的编码 |
Content-Encoding |
响应正文使用的数据压缩格式 |
Content-Language |
响应正文使用的语言 |
响应示例:
HTTP/1.1 200 OK
Bdpagetype: 2
Bdqid: xxx
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Sat, 10 Aug 2019 08:00:56 GMT
Expires: Sat, 10 Aug 2019 08:00:56 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=269; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=xxx; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Transfer-Encoding: chunked
X-Ua-Compatible: IE=Edge,chrome=1
响应正文
对应的响应正文
<!DOCTYPE html>
<html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a> <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a> 京ICP证030173号 <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
HTTP请求GET和POST的区别
1.GET提交,请求的数据会附在URL之后(就是把数据放置在HTTP协议头<request-line>中),以?分割URL和传输数据,多个参数用&连接;例如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
POST提交:把提交的数据放置在是HTTP包的包体<request-body>中。上文示例中红色字体标明的就是实际的传输数据
因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变
2.传输数据的大小:
首先声明,HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。 而在实际开发中存在的限制主要有:
GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
因此对于GET提交时,传输数据就会受到URL长度的限制。
POST:由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
3.安全性:
POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存, (2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了
References
[1] 一篇文章带你熟悉 TCP/IP 协议(网络协议篇二)
[2] 一篇文章带你详解 HTTP 协议(网络协议篇一)
[3] Http 和 Socket 到底是哪门子亲戚
[4] 你必须知道的HTTP基本概念
[5] 你必须知道的HTTP基本概念
[6] 一文读懂OSI七层模型与TCP/IP四层的区别/联系
[7] 前端经典面试题: 从输入URL到页面加载发生了什么?
[8] 从输入 URL 到页面加载完成的过程中都发生了什么事情?
[9] OSI模型的通俗理解以及和TCP-IP模型的区别
[10] HTTP详解(1)-工作原理
[11] HTTP请求报文和HTTP响应报文
[12] HTTP请求、响应报文格式