浅谈HTTP事务的一个过程

导语:经典的面试题,当我们在浏览器中输入地址,发生了什么?来看看这位伙伴的6步骤。1.域名解析、2.发起TCP的3次握手、3.发起HTTP请求……

一个腾讯在职的朋友问道,当我们在浏览器的地址栏输入 www.baidu.com ,然后回车,这一瞬间页面发生了什么?下面以谷歌浏览器一一解释.

一.域名解析

首先Chrome浏览器会解析www.baidu.com 这个域名对应的IP地址。

1 浏览器搜索自身的DNS缓存,看是否有www.baidu.com 对应的条目,如果有且没有过期则解析到此结束。

2 如果没有找到对应的条目,那么Chrome会搜索操作系统自身的DNS缓存,如果找到且没过期则停止搜索解析到此结束.

3 如果在Windows系统的DNS缓存也没有找到,那么尝试读取hosts文件,看有没有该域名对应的IP地址,如果有则解析成功。

4 如果在hosts文件中也没有找到对应的条目,浏览器就会发起一个DNS的系统调用,就会向本地配置的首选DNS服务器发起域名解析请求,运营商的DNS服务器首先查找自身的缓存,找到对应的条目,且没有过期,则解析成功。

二.发起TCP的3次握手

拿到域名对应的IP地址后,User-Agent(一般是指浏览器)会以一个随机端口(1024 < 端口 < 65535)向服务器的WEB程序80端口发起TCP的连接请求。这个连接请求(原始的http请求经过TCP/IP4层模型的层层封包)到达服务器端后,进入到网卡,然后是进入到内核的TCP/IP协议栈,还有可能要经过Netfilter防火墙的过滤,最终到达WEB程序,建立了TCP/IP的连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接:

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“第四次握手”,就是服务器和客户端交互,最终确定断开。

三.建立TCP连接后发起http请求

HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。

1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接求。通常 的做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

进过TCP3次握手之后,浏览器发起了http的请求,使用的http的方法 GET 方法,请求的URL是 / ,协议是HTTP/1.0。那么HTTP请求报文和响应报文会是什么格式呢?

起始行:如 GET / HTTP/1.0 (请求的方法、请求的URL 请求所使用的协议)

头部信息:User-Agent  Host等成对出现的值

主体

起始行中的请求方法有以下:

GET

GET是http的默认请求方式,一般用来获取数据,传输的数据经过url编码后放在路径?之后,多个键值对通过&连接,另外get的传输长度一般不推荐超过255个字节。

GET方法一般被视为安全方法, 因为它仅用来获取数据而不会对服务器有其他改动。像HEAD、GET、OPTIONS 和 TRACE这几种http方法是被认为是“安全的”,它们只会进行获取数据而不会修改服务器的状态,可用于记录日志、创建缓存或者创建其他统计信息。相反,像POST、PUT、DELETE 和 PATCH 等方法是有可能产生副作用。网络爬虫等一般不会使用这些方式

POST

POST一般用来上传文件或者提交一个完整的web表单。浏览器中提交表单时,这里与get类似,每个键值对都是通过&分割, 其他非字母数字会进行url转码。

为什么一些请求会使用POST提交数据?

  1. GET请求数据都可以在URL中看到
  2. GET提交的数据都会有长度限制
  3. 一般规范,POST用来修改数据,GET用来获取数据
  4. GET请求提交的数据放置在HTTP请求协议头中,而POST提交的数据放在实体数据中

其他请求方式

HEAD获取某个URI响应头信息,基本与GET相同但是不返回响应主体。

PUT通过提供的URI获取到特定的内容主体,如果存在则修改内容,如果不存在则创建。

DELETE通过URI删除指定内容

TRACE返回接受到的请求,用来查看数据经过中间服务器时发生了哪些变动

OPTIONS返回给定URL支持的所有HTTP方法

CONNECT要求使用SSL和TLS进行TCP通信

PATCH请求修改局部数据

那什么是URLURIURN

URI  Uniform Resource Identifier 统一资源标识符

URL  Uniform Resource Locator 统一资源定位符

格式如下:  scheme://[username:password@]HOST:port/path/to/source

http://www.magedu.com/downloads/nginx-1.5.tar.gz

URN  Uniform Resource Name 统一资源名称。URL和URN 都属于 URI。为了方便就把URL和URI暂时都通指一个东西

下面是Chrome发起的http请求报文头部信息:

757222-20160424203816898-1768005406

Accept  就是告诉服务器端,我接受那些MIME类型

Accept-Encoding  这个看起来是接受那些压缩方式的文件

Accept-Lanague   告诉服务器能够发送哪些语言

Connection       告诉服务器支持keep-alive特性

Cookie           每次请求时都会携带上Cookie以方便服务器端识别是否是同一个客户端

Host             用来标识请求服务器上的那个虚拟主机,比如Nginx里面可以定义很多个虚拟主机.那这里就是用来标识要访问那个虚拟主机。

User-Agent       用户代理,一般情况是浏览器,也有其他类型,如:wget curl 搜索引擎的蜘蛛等

条件请求首部:

If-Modified-Since 是浏览器向服务器端询问某个资源文件如果自从什么时间修改过,那么重新发给我,这样就保证服务器端资源.文件更新时,浏览器再次去请求,而不是使用缓存中的文件

安全请求首部:

Authorization: 客户端提供给服务器的认证信息;

什么是MIME

MIME(Multipurpose Internet Mail Extesions 多用途互联网邮件扩展)是一个互联网标准,它扩展了电子邮件标准,使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息,这个标准被定义在RFC 2045、RFC 2046、RFC 2047、RFC 2048、RFC 2049等RFC中。 由RFC 822转变而来的RFC 2822,规定电子邮件标准并不允许在邮件消息中使用7位ASCII字符集以外的字符。正因如此,一些非英语字符消息和二进制文件,图像,声音等非文字消息都不能在电子邮件中传输。MIME规定了用于表示各种各样的数据类型的符号化方法。 此外,在万维网中使用的HTTP协议中也使用了MIME的框架,标准被扩展为互联网媒体类型。

MIME 遵循以下格式:major/minor 主类型/次类型 例如:

image/jpg

image/gif

text/html

video/quicktime

appliation/x-httpd-php

四.服务器端响应http请求,浏览器得到html代码

服务器端WEB程序接收到http请求以后,就开始处理该请求,处理之后就返回给浏览器html文件。

1xx: 信息性状态码

100, 101

2xx: 成功状态码

200:OK

3xx: 重定向状态码

301: 永久重定向, Location响应首部的值仍为当前URL,因此为隐藏重定向;

302: 临时重定向,显式重定向, Location响应首部的值为新的URL

304:Not Modified  未修改,比如本地缓存的资源文件和服务器上比较时,发现并没有修改,服务器返回一个304状态码,告诉浏览器,你不用请求该资源,直接使用本地的资源即可。

4xx: 客户端错误状态码

404: Not Found  请求的URL资源并不存在

5xx: 服务器端错误状态码

500: Internal Server Error  服务器内部错误

502: Bad Gateway  前面代理服务器联系不到后端的服务器时出现

504:Gateway Timeout  这个是代理能联系到后端的服务器,但是后端的服务器在规定的时间内没有给代理服务器响应

用Chrome浏览器看到的响应头信息:

757222-20160424205128210-565643324

Connection            使用keep-alive特性

Content-Encoding      使用gzip方式对资源压缩

Content-type          MIME类型为html类型,字符集是 UTF-8

Date                  响应的日期

Server                使用的WEB服务器

Transfer-Encoding:chunked   分块传输编码 是http中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用(通常是网页浏览器)的数据可以分成多个部分,分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供

五. 浏览器解析html代码,并请求html代码中的资源

浏览器拿到index.html文件后,就开始解析其中的html代码,遇到js/css/image等静态资源时,就向服务器端去请求下载(会使用多线程下载,每个浏览器的线程数不一样),这个时候就用上keep-alive特性了,建立一次HTTP连接,可以请求多个资源,下载资源的顺序就是按照代码里的顺序,但是由于每个资源大小不一样,而浏览器又多线程请求请求资源,顺序并不一定是代码里面的顺序。

浏览器在请求静态资源时(在未过期的情况下),向服务器端发起一个http请求(询问自从上一次修改时间到现在有没有对资源进行修改),如果服务器端返回304状态码(告诉浏览器服务器端没有修改),那么浏览器会直接读取本地的该资源的缓存文件。

六.浏览器对页面进行渲染呈现给用户

最后,浏览器把请求到的静态资源和html代码进行渲染,呈现给用户。

总结

域名解析 –> 发起TCP的3次握手 –> 建立TCP连接后发起http请求 –> 服务器响应http请求,浏览器得到html代码 –> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) –> 浏览器对页面进行渲染呈现给用户

https://github.com/LYZ0106/

关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流