HTTP和HTTPS
本文最后更新于:星期一, 九月 12日 2022, 1:25 凌晨
浏览器输入url地址到显示主页的过程
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
DNS解析
DNS解析的过程就是寻找哪台机器上有你需要资源的过程。当你在浏览器中输入一个地址,例如www.baidu.com
,其实不是真正意义上的地址。互联网上每台计算机的唯一标识是它的IP地址,但是IP地址并不方便记忆。用户更喜欢用方便记忆的网址去寻找互联网上的其它计算机,也就是上面提到的百度网址。所以需要在用户的方便性与可用性方面做一个权衡,这个权衡就是一个网址到IP地址的转换,整个过程就是DNS解析。它实际上充当了一个翻译的角色。
实现了网址到IP地址的转换。网址到IP地址转换的过程是如何进行的?
- DNS解析是一个递归查询的过程
首先在本地域名服务器中查询IP地址,如果没有找到,本地域名服务器会向根域名服务器发送一个请求,如果根域名服务器也不存在该域名,本地域名会向com顶级域名服务器发送一个请求,依次类推下去。直到最后本地域名服务器得到baidu的IP地址并把它缓存到本地,供下次查询使用。从上述过程中,可以看出网址的解析是一个从右向左的过程:com -> baidu.com -> www.baidu.com
。但是你是否发现少了点什么,根域名服务器的解析过程呢?事实上,真正的网址是www.baidu.com.
,并不是我多打了一个.
,这个.
对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.
,既然是默认情况,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上,所以网址真正的解析过程为:. -> .com -> baidu.com. -> www.baidu.com.
- DNS优化
上文中请求到baidu的IP地址时,经历了多个步骤,这个过程中存在多个请求。如果每次都经过这么多步骤,是否太耗时间?如何减少该过程的步骤呢?那就是使用DNS缓存
DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存 - DNS负载均衡
DNS返回的IP地址是否每次都一样?如果每次都一样是否说明你请求的资源都位于同一台机器上,那么这台机器需要多高的性能和储存才能满足亿万请求呢?其实真实的互联网世界背后存在成千上百台服务器,大型的网站甚至更多。但在用户眼里,它需要的只是处理它的请求,哪台机器处理请求并不重要。DNS可以返回一个合适的机器IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡,又叫做DNS重定向。大家耳熟能详的CDN(Content Delivery Network)就是利用DNS的重定向技术,DNS服务器会返回一个跟用户最接近的点的IP地址给用户,CDN节点的服务器负责响应用户的请求,提供所需的内容
TCP连接
HTTP协议是使用TCP作为其传输层协议的,当TCP出现瓶颈时,HTTP也会受到影响。
- HTTPS协议
HTTP报文是包裹在TCP报文中发送的,服务器端收到TCP报文时会解包提取出HTTP报文。但是这个过程中存在一定的风险,HTTP报文是明文,如果中间被截取的话会存在一些信息泄露的风险。那么在进入TCP报文之前对HTTP做一次加密就可以解决这个问题了。HTTPS协议的本质就是HTTP + SSL(或TLS)。在HTTP报文进入TCP报文之前,先使用SSL对HTTP报文进行加密。从网络的层级结构看它位于HTTP协议与TCP协议之间,如图
- HTTPS过程
HTTPS在传输数据之前需要客户端与服务器进行一个握手(TLS/SSL握手),在握手过程中将确立双方加密传输数据的密码信息。TLS/SSL使用了非对称加密、对称加密以及hash等
HTTPS相比于HTTP,虽然提供了安全保证,但是势必会带来一些时间上的损耗,如握手和加密等过程,是否使用HTTPS需要根据具体情况在安全和性能方面做出权衡
发送HTTP请求
这部分又可以称为前端工程师眼中的HTTP,它主要发生在客户端。发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口(HTTP协议80/8080, HTTPS协议443)。
HTTP请求报文是由三部分组成: 请求行、请求报头和请求正文
请求行
格式如下Method Request-URL HTTP-Version
代码示例
GET index.html HTTP/1.1
常用的方法有: GET、POST、PUT、DELETE、OPTIONS、HEAD
对这些方法说明见下方表格
方法 描述 GET 从指定的资源请求数据 POST 向指定的资源提交要被处理的数据 PUT 上传指定的 URI 表示 DELETE 删除指定资源 HEAD 与 GET 相同,但只返回 HTTP 报头,不返回文档主体 OPTIONS 返回服务器支持的 HTTP 方法 CONNECTION 把请求连接转换到透明的 TCP/IP 通道 GET和POST区别
- GET在浏览器回退时是无害的,而POST会再次提交请求
- GET产生的URL地址可以被Bookmark,而POST不可以
- GET请求会被浏览器主动cache,而POST不会,除非手动设置
- GET请求只能进行url编码,而POST支持多种编码方式
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留
- GET请求在URL中传送的参数是有长度限制的,而POST么有
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
- GET参数通过URL传递,POST放在Request body中
请求报头
请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。
PS: 客户端不一定特指浏览器,有时候也可使用Linux下的CURL命令以及HTTP客户端测试工具(postman)等。
常见的请求报头有: Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Type、Authorization、Cookie、User-Agent等请求正文
当使用POST,PUT等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求报头中有一些与请求正文相关的信息,比如现在的Web应用通常采用Rest架构,请求的数据格式一般为json。这时就需要设置Content-Type: application/json
服务器处理请求并返回HTTP报文
这部分对应的就是后端工程师眼中的HTTP。后端从在固定的端口接收到TCP报文开始,这一部分对应于编程语言中的socket。它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般由Web服务器进行,Web服务器有Tomcat, Jetty和Netty等等。
HTTP响应报文也是由三部分组成: 状态码、响应报头和响应报文
状态码
如图常见的状态码有:200、204、301、302、304、400、401、403、404、500
状态码 英文名 中文描述 200 OK 请求成功。
一般用于GET与POST请求204 No Content 无内容。
服务器成功处理,
但未返回内容。
在未更新网页的情况下,
可确保浏览器继续显示当前文档301 Moved Permanently 永久移动。
请求的资源已被永久的移动
到新URI,
返回信息会包括新的URI,
浏览器会自动定向到新URI。
今后任何新的请求都应使用新的
URI代替302 Found 临时移动。
与301类似。
但资源只是临时被移动。
客户端应继续使用原有URI304 Not Modified 未修改。
所请求的资源未修改,
服务器返回此状态码时,
不会返回任何资源。
客户端通常会缓存访问过的资源,
通过提供一个头信息指出
客户端希望只返回
在指定日期之后修改的资源400 Bad Request 客户端请求的语法错误,
服务器无法理解401 Unauthorized 请求要求用户的身份认证 403 Forbidden 服务器理解请求客户端的请求,
但是拒绝执行此请求404 Not Found 服务器无法根据客户端的请求
找到资源(网页)。
通过此代码,
网站设计人员可设置
“您所请求的资源无法找到”
的个性页面500 Internal Server Error 服务器内部错误,无法完成请求 301和302区别
- 301表示被请求url永久转移到新的url;302表示被请求url临时转移到新的url
- 301搜索引擎会索引新url和新url页面的内容;302搜索引擎可能会索引旧url和新url的页面内容
- 302会发生网址劫持(URL hijacking),302返回码可能会被别人利用,劫持你的网址。因为搜索引擎索引他的网址,他会返回302跳转到你的页面
响应报头
常见的响应报头字段有: Server、Connection响应报文
服务器返回给浏览器的文本信息,通常指HTML、CSS、JS、图片等文件
浏览器解析渲染页面
浏览器是一个边解析边渲染的过程。首先浏览器解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)。DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为relow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应尽可能少的减少reflow和repain。其实如果去面试,知道这个步骤是渲染HTML,CSS,JS文件就行
HTTP工作原理
版本描述
http1.0
指定keep-alive来开启持久连接,默认是短连接,浏览器每次请求都要重新建立一次tcp连接(3次握手),结束就释放tcp连接(4次挥手)
http1.1
默认支持长连接,浏览器打开一个网页之后,底层的tcp连接就保持着,不会立马断开,之后加载css、js之类的请求,都会基于这个tcp连接来走。http1.1还支持host头,也就可以支持虚拟主机;而且对断点续传有支持
浏览器第一次请求一个网站的一个页面时,会打开一个tcp连接,接着在一段时间内都不关闭,接下来这个网页加载css、js、图片大量的请求全部走同一个tcp连接,频繁的发送请求获取响应,最后过了一段时间,全部结束了,才会去释放那一个tcp连接。大幅度提升了复杂网页打开的速度和性能
http2.0
支持多路复用,基于一个tcp连接并行发送多个请求以及接收响应,解决了http1.1对同一时间同一个域名的请求有限制的问题。二进制分帧,将传输数据拆分为更小的帧(数据包),frame(数据包,帧),提高性能,实现低延迟、高吞吐
长连接
http本身没什么所谓的长连接短连接之说,说白了都是http(应用层)下层的tcp(传输层)连接是长连接还是短连接,tcp连接保持长连接,那么多个http请求和响应都可以通过这一个链接来走。http1.1之后,默认都是长连接了,就底层都是一个网页一个tcp连接,一个网页的所有图片、css、js的资源加载,都走底层一个tcp连接,来多次http请求都可以
http1.0时,底层的tcp是短连接,一个网页发起的请求,每个请求都是先tcp三次握手,然后发送请求,获取响应,然后tcp四次挥手断开连接;每个请求,都会先连接再断开。短连接,建立连接之后,发送个请求,直接连接就给断开了
http1.1,tcp长连接,tcp三次握手,建立了连接,无论有多少次请求都是走一个tcp连接的,走了n多次请求之后,然后tcp连接被释放掉了
HTTPS工作原理
接下来具体说明加密解密过程
- 浏览器把自己支持的加密规则发送给网站
- 网站从这套加密规则里选出来一套加密算法和hash算法,然后把自己的身份信息用证书的方式发回给浏览器,证书里有网站地址、加密公钥、证书颁发机构
- 浏览器验证证书的合法性,然后浏览器地址栏上会出现一把小锁;浏览器接着生成一串随机数密码,然后用证书里的公钥进行加密,这块走的非对称加密;用约定好的hash算法生成握手消息的hash值,然后用密码对消息进行加密,然后把所有东西都发给网站,这块走的是对称加密
- 网站,从消息里面可以取出来公钥加密后的随机密码,用本地的私钥对消息解密取出来密码,然后用密码解密浏览器发来的握手消息,计算消息的hash值,并验证与浏览器发送过来的hash值是否一致,最后用密码加密一段握手消息,发给浏览器
- 浏览器解密握手消息,然后计算消息的hash值,如果跟网站发来的hash一样,握手就结束,之后所有的数据都会由之前浏览器生成的随机密码,然后用对称加密来进行进行加密
常用的非对称加密是RSA算法,对称加密是AES、RC4等,hash算法就是MD5
参考资料
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!