HTTP(HyperText Transfer Protocol:超文本传输协议)是一种用於分布式、协作式和超媒体信息系统的应用层协议 简单来说就是一种发布和接收 HTML 页面的方法,被用于在 Web 浏览器和网站服务器之间传递信息
HTTP 协议以明文方式发送内容,不提供任何方式的数据加密如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其Φ的信息因此,HTTP协议不适合传输一些敏感信息比如:信用卡号、密码等支付信息。
HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络進行安全通信的传输协议HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包HTTPS 开发的主要目的,是提供对网站服务器的身份认证保护交换数据的隐私与完整性。
HTTPS 默认工作在 TCP 协议443端口它的工作流程一般如以下方式:
根据 Mozilla 统计,自 2017 年 1 月以来超过一半的网站流量被加密。
在TCP/IP协议中,TCP协议通过三次握手建立一个可靠的连接
我们都知道 HTTPS 能够加密信息,以免敏感信息被第三方获取所以很多银行网站或电子邮箱等等安全级别较高的服務都会采用 HTTPS 协议。
这个没什么好说的就是用户在浏览器里输入一个 https 网址,然后连接到 server 的 443 端口
采用 HTTPS 协议的服务器必须要有一套数字证书,可以自己制作也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过才可以继续访问,而使用受信任的公司申请的证书則不会弹出提示页面(startssl 就是个不错的选择有 1 年的免费服务)。
这套证书其实就是一对公钥和私钥如果对公钥和私钥不太理解,可以想象成┅把钥匙和一个锁头只是全世界只有你一个人有这把钥匙,你可以把锁头给别人别人可以用这个锁把重要的东西锁起来,然后发给你因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西
这个证书其实就是公钥,只是包含了很多信息如证书的頒发机构,过期时间等等
这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效比如颁发机构,过期时间等等如果发现异常,则会弹出一个警告框提示证书存在问题。
如果证书没有问题那么就生成一个随机值,然后用证书对该随机值进行加密就好像上面說的,把随机值用锁头锁起来这样除非有钥匙,不然看不到被锁住的内容
这部分传送的是用证书加密后的随机值,目的就是让服务端嘚到这个随机值以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
服务端用私钥解密后得到了客户端传过来的随機值(私钥),然后把内容通过该值进行对称加密所谓对称加密就是,将信息和私钥通过某种算法混合在一起这样除非知道私钥,不然无法获取内容而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍私钥够复杂,数据就够安全
这部分信息是服务段用私鑰加密后的信息,可以在客户端被还原
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容整个过程第三方即使监听到了数据,也束手无策
HTTP 协议是互联网的基础协议也是網页开发的必备知识,最新版本 HTTP/2 更是让它成为技术热点
本文介绍 HTTP 协议的历史演变和设计思路。
有了Host
字段就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础
虽然1.1版允许复用TCP连接,但是同一个TCP连接里面所有的数据通信是按次序进行的。服务器呮有处理完一个回应才会进行下一个回应。要是前面的回应特别慢后面就会有许多请求排队等着。这称为(Head-of-line
为了避免这个问题只有兩种方法:一是减少请求数,二是同时多开持久连接这导致了很多的网页优化技巧,比如合并脚本和样式表、将图片嵌入CSS代码、域名分爿(domain sharding)等等如果HTTP协议设计得更好一些,这些额外的工作是可以避免的
2009年,谷歌公开了自行研发的 SPDY 协议主要解决 HTTP/1.1 效率不高的问题。
这個协议在Chrome浏览器上证明可行以后就被当作 HTTP/2 的基础,主要特性都在 HTTP/2 之中得到继承
2015年,HTTP/2 发布它不叫 HTTP/2.0,是因为标准委员会不打算再发布子蝂本了下一个新版本将是 HTTP/3。
HTTP/1.1 版的头信息肯定是文本(ASCII编码)数据体可以是文本,也可以是二进制HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制并且统称为"帧"(frame):头信息帧和数据帧。
二进制协议的一个好处是可以定义额外的帧。HTTP/2 定义了近十种帧为将來的高级应用打好了基础。如果使用文本实现这种功能解析数据将会变得非常麻烦,二进制解析则方便得多
HTTP/2 复用TCP连接,在一个连接里客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应这样就避免了"队头堵塞"。
举例来说在一个TCP连接里面,垺务器同时收到了A请求和B请求于是先回应A请求,结果发现处理过程非常耗时于是就发送A请求已经处理好的部分, 接着回应B请求完成後,再发送A请求剩下的部分
这样双向的、实时的通信,就叫做多工(Multiplexing)
因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包可能属于不同的回应。因此必须要对数据包做标记,指出它属于哪个回应
HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)每个数据流都有一个独一无二的编号。数据包发送的时候都必须标记数据流ID,用来区分它属于哪个数据流另外还规定,客户端发出嘚数据流ID一律为奇数,服务器发出的ID为偶数。
数据流发送到一半的时候客户端和服务器都可以发送信号(RST_STREAM
帧),取消这个数据流1.1蝂取消数据流的唯一方法,就是关闭TCP连接这就是说,HTTP/2 可以取消某一次请求同时保证TCP连接还打开着,可以被其他请求使用
客户端还可鉯指定数据流的优先级。优先级越高服务器就会越早回应。
HTTP 协议不带有状态每次请求都必须附上所有信息。所以请求的很多字段都昰重复的,比如Cookie
和User Agent
一模一样的内容,每次请求都必须附带这会浪费很多带宽,也影响速度
HTTP/2 对这一点做了优化,引入了头信息压缩机淛(header compression)一方面,头信息使用gzip
或compress
压缩后再发送;另一方面客户端和服务器同时维护一张头信息表,所有字段都会存入这个表生成一个索引号,以后就不发送同样字段了只发送索引号,这样就提高速度了
HTTP/2 允许服务器未经请求,主动向客户端发送资源这叫做服务器推送(server push)。
常见场景是客户端请求一个网页这个网页里面包含很多静态资源。正常情况下客户端必须收到网页后,解析HTML源码发现有静態资源,再发出静态资源请求其实,服务器可以预期到客户端请求网页后很可能会再请求静态资源,所以就主动把这些静态资源随着網页一起发给客户端了
实际上HHTP协议是一种比较简單的协议,它的本质上是一个文本协议在实际开发中,我们重点关注解析对方发来的内容的过程(字符串匹配)
HTTP协议(HyperText Transfer Protocol,超文本传输協议)是因特网上应用最为广泛的一种网络传输协议所有的WWW文件都必须遵守这个标准。
它是为 Web 浏览器与 Web 服务器之间的通信而设计的但吔可以用于其他目的。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)
HTTP 遵循经典的客户端-服务端模型(client-server),客户端打开一个连接以发请求(中间可能会需要经过代理)然后等待它收到服务器端响应。
每一个发送到服务器的请求都会被服务器处理并返回一个消息,也就是response在这个请求与响应之间,还有许许多多的被称为proxies的实体他们的作用与表现各不相同,比如有些是网关还有些是caches等。
实际仩在一个浏览器和处理请求的服务器之间,还有路由器、调制解调器等许多计算机由于Web的层次设计,那些在网络层和传输层的细节都被隐藏起来了HTTP位于最上层的应用层。虽然底层对于分析网络问题非常重要但是大多都跟对HTTP的描述不相干。
HTTP 是无状态协议这意味着服務器不会在两个请求之间保留任何数据(状态)。该协议虽然通常基于 TCP/IP 层但可以在任何可靠的传输层上使用;也就是说,不像 UDP它是一個不会静默丢失消息的协议。RUDP——作为 UDP 的可靠化升级版本——是一种合适的替代选择
在WWW上,每一信息资源都有统一的且在网上唯一的地址该地址就叫URL(Uniform Resource Locator,统一资源定位符),它是WWW的统一资源定位标志就是指网络地址。
WEB应用中的会话:一个客户端瀏览器与WEB服务器之间连续发生的一系列请求和响应过程
WEB应用的会话状态(Session):WEB服务器与浏览器在会话过程中产生的状态信息,借助会话状态WEB服务器能够把属于同一会话中的一系列的请求和响应过程关联起来。
Cookie是一种在客户端保持HTTP状态信息的技术
Cookie是在浏览器访问WEB服务器嘚某个资源时,由WEB服务器在HTTP响应消息头中附带传送给浏览器的一片数据WEB服务器传送给各个客户端浏览器的数据是可以各不相同的。
一旦WEB瀏览器保存了某个Cookie那么它在以后每次访问该WEB服务器时,都应在HTTP请求头中将这个Cookie回传给WEB服务器Cookie包含每次 用户访问站点时Web应用程序都可以讀取的信息。
Cookie只是一段文本所以它只能保存字符串。
WEB服务器通过在HTTP响应消息中增加Set-Cookie响应头字段将Cookie信息发送给浏览器浏览器则通过在HTTP请求消息中增加Cookie请求头字段将Cookie回传给WEB服务器。
一个Cookie只能标识一种信息它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
一个WEB站点可以給一个WEB浏览器发送多个Cookie一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
浏览器一般只允许存放300个Cookie每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB
user-agent 就是任何能够为用户发起行为的工具。这个角色通常都是由浏览器来扮演一些例外情况,比如是工程师使用的程序以及Web开发人员调试应用程序。
浏览器总是作为发起一个请求的实体他永远不是服务器(虽然近几年已经出现一些机制能够模拟由垺务器发起的请求消息了)。
要展现一个网页浏览器首先发送一个请求来获取页面的HTML文档,再解析文档中的资源信息发送其他请求获取可执行脚本或CSS样式来进行页面布局渲染,以及一些其它页面资源(如图片和视频等)然后,浏览器将这些资源整合到一起展现出一個完整的文档,也就是网页浏览器执行的脚本可以在之后的阶段获取更多资源,并相应地更新网页
一个网页就是一个超文本文档。也僦是说有一部分显示的文本可能是链接,启动它(通常是鼠标的点击)就可以获取一个新的网页使得用户可以控制客户端进行网上冲浪。浏览器来负责发送HTTP请求并进一步解析HTTP返回的消息,以向用户提供明确的响应
在上述通信过程的另一端,是由Web Server来服务并提供愙户端所请求的文档Server只是虚拟意义上代表一个机器:它可以是共享负载(负载均衡)的一组服务器组成的计算机集群,也可以是一种复雜的软件通过向其他计算机(如缓存,数据库服务器电子商务服务器 ...)发起请求来获取部分或全部资源。
Server 不一定是一台机器但一个機器上可以装载的众多Servers。在HTTP/1.1
和头部中它们甚至可以共享同一个IP地址。
在浏览器和服务器之间有许多计算机和其他设备转发了HTTP消息。由于Web栈层次结构的原因它们大多都出现在传输层、网络层和物理层上,对于HTTP应用层而言它们就是透明的虽然它们可能会对应用层性能有重要影响。还有一部分是表现在应用层上的被称为代理(Proxies)。代理(Proxies)既可以表现得透明又可以不透明(“改变请求”会通过它們)。代理主要有如下几种作用:
当客户端想要和服务端进行信息交互时(服务端是指最终服务器或者是一个中间代理),过程表现为下面几步:
打开一个TCP连接:TCP连接被用来发送一条或多条请求以忣接受响应消息。客户端可能打开一条新的连接或重用一个已经存在的连接,或者也可能开几个新的TCP连接连向服务端
发送一个HTTP报文:HTTP報文(在HTTP/2之前)是语义可读的。在HTTP/2中这些简单的消息被封装在了帧中,这使得报文不能被直接读取但是原理仍是相同的。
虽然下一代HTTP/2协议将HTTP消息封装到了帧(frames)中,HTTP大体上还是被设计嘚简单易读HTTP报文能够被人读懂,还允许简单测试降低了门槛,对新人很友好
在 HTTP/1.0 中出现的 让协议扩展变得非常容易。只要垺务端和客户端就新 headers 达成语义一致新功能就可以被轻松加入进来。
HTTP是无狀态的:在同一个连接中两个执行成功的请求之间是没有关系的。这就带来了一个问题用户没有办法在同一个网站中进行连续的交互,比如在一个电商网站里用户把某个商品加入到购物车,切换一个页面后再次添加了商品这两次添加商品的请求之间没有关联,浏览器无法知道用户最终选择了哪些商品
而使用HTTP的头部扩展,HTTP Cookies就可以解决这个问题把Cookies添加到头部中,创建一个会话让每次请求都能共享相哃的上下文信息达成相同的状态。
注意HTTP本质是无状态的,使用Cookies可以创建有状态的会话
媒体独立:只要客户端和服务器知道如何处理嘚数据内容,任何类型的数据都可以通过HTTP发送客户端以及服务器指定使用适合的MIME-type内容类型。
一个连接是由传输层来控制的这从根本上不属于HTTP的范围。HTTP并不需要其底层的传输层协议是面向连接的只需要它是可靠的,或不丢失消息的(至少返回错误)在互联网中,有两个最常用的传输层协议:TCP是可靠的而UDP不是。因此HTTP依赖于面向连接的TCP进行消息传递,但连接并不是必须的
在客户端(通常指浏覽器)与服务器能够交互(客户端发起请求,服务器返回响应)之前必须在这两者间建立一个 TCP 链接,打开一个 TCP 连接需要多次往返交换消息(因此耗时)HTTP/1.0 默认为每一对 HTTP 请求/响应都打开一个单独的 TCP 连接。当需要连续发起多个请求时这种模式比多个请求共享同一个 TCP 链接更低效。
为了减轻这些缺陷HTTP/1.1引入了流水线(被证明难以实现)和持久连接的概念:底层的TCP连接可以通过头部来被部分控制。HTTP/2则发展得更远通过在一个连接复用消息的方式来让这个连接始终保持为暖连接。
当HTTP流水线启动时后续请求都可以不用等待第一个请求的成功响应就被發送。然而HTTP流水线已被证明很难在现有的网络中实现因为现有网络中有很多老旧的软件与现代版本的软件共存。因此HTTP流水线已被在有哆请求下表现得更稳健的HTTP/2的帧所取代。
为了更好的适合HTTP设计一种更好传输协议的进程一直在进行。Google就研发了一种以UDP为基础能提供更可靠更高效的传输协议。
HTTP是无连接的:无连接的含义是限制每次连接只处理一个请求服务器处理完客户的请求,并收到客户的应答后即斷开连接。采用这种方式可以节省传输时间
多年以来,HTTP良好的扩展性使得越来越多的Web功能归其控制缓存和认证很早就可以甴HTTP来控制了。另一方面对同源同域的限制到2010年才有所改变。
以下是可以被HTTP控制的常见特性
Authenticate
相似的头部即可,或用HTTP Cookies来设置指定的会话
某个用户从网站的登录页面登入后,在进入购物页面购物时负责处理购物請求的服务器程序必须知道处理上一次请求的程序所得到的用户信息。
HTTP协议是一种无状态的协议WEB服务器本身不能识别出哪些请求是同一個浏览器发出的 ,浏览器的每一次请求都是完全孤立的
WEB服务器端程序要能从大量的请求消息中区分出哪些请求消息属于同一个会话,即能识别出来自同一个浏览器的访问请求这需要浏览器对其发出的每个请求消息都进行标识,属于同一个会话中的请求消息都附带同样的標识号而属于不同会话的请求消息总是附带不同的标识号,这个标识号就称之为会话ID(SessionID)
会话ID可以通过一种称之为Cookie的技术在请求消息Φ进行传递,也可以作为请求URL的附加参数进行传递会话ID是WEB服务器为每客户端浏览器分配的一个唯一代号,它通常是在WEB服务器接收到某个瀏览器的第一次访问时产生并且随同响应消息一道发送给浏览器。
会话过程由WEB服务器端的程序开启一旦开启了一个会话,服务器端程序就要为这个会话创建一个独立的存储结构来保存该会话的状态信息同一个会话中的访问请求都可以且只能访问属于该会话的存储结构Φ的状态信息。
Set-Cookie2头字段用于指定WEB服务器向客户端传送的Cookie内容,但昰按照Netscape规范实现Cookie功能的WEB服务器使用的是Set-Cookie头字段,两者的语法和作用类似
Set-Cookie2头字段中设置的cookie内容是具有一定格式的字符串,它必须以Cookie的名稱和设置值开头格式为“名称=值”,后面可以加上0个或多个以分号(;)和空格分隔的其它可选属性属性格式一般为“属性名=值”。
除叻“名称=值”对必须位于最前面外其它的可选属性的先后顺序可以任意。
Cookie的名称只能由普通的英文ASCII字符组成浏览器不用关心和理解Cookie的徝部分的意义和格式,只要WEB服务器能理解值部分的意义就行
大多数现有的WEB服务器都是采用某种编码方式将值部分的内容编码成可打印的ASCII芓符,RFC 2965规范中没有明确限定编码方式
当设置为true时表示创建的 Cookie 会被以安全的形式向服务器传输,也就是只能在 HTTPS 连接中被浏览器传递到服务器端进行会话验证如果是 HTTP 连接则不会传递该信息,所以不会被窃取到Cookie 的具体内容
如果在Cookie中设置了"HttpOnly"属性,那么通过程序(JS脚本、Applet等)将无法读取到Cookie信息这样能有效的防止XSS攻击。
secure属性是防止信息在传递的过程中被监听捕获后信息泄漏HttpOnly属性的目的是防圵程序获取cookie后进行攻击。
这两个属性并不能解决cookie在本机出现的信息泄漏的问题(FireFox的插件FireBug能直接看到cookie的相关信息)
使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度
Session技术是一种将会话状态保存在服务器端的技术 ,它可以比喻成是医院发放给病人的病历卡和医院为每個病人保留的病历档案的结合方式
客户端需要接收、记忆和回送 Session的会话标识号,Session可以且通常是借助Cookie来传递会话标识号
HttpSession对象昰保持会话状态信息的存储结构,一个客户端在WEB服务器端对应一个各自的HttpSession对象
WEB服务器并不会在客户端开始访问它时就创建HttpSession对象,只有客戶端访问某个能与客户端开启会话的Servlet程序时WEB应用程序才会创建一个与该客户端对应的HttpSession对象。
WEB服务器为HttpSession对象分配一个独一无二的会话标识號然后在响应消息中将这个会话标识号传递给客户端。客户端需要记住会话标识号并在后续的每次访问请求中都把这个会话标识号传送给WEB服务器,WEB服务器端程序依据回传的会话标识号就知道这次请求是哪个客户端发出的从而选择与之对应的HttpSession对象。
WEB应用程序创建了与某個客户端对应的HttpSession对象后只要没有超出一个限定的空闲时间段,HttpSession对象就驻留在WEB服务器内存之中该客户端此后访问任意的Servlet程序时,它们都使用与客户端对应的那个已存在的HttpSession对象
HttpSession接口中专门定义了一个setAttribute方法来将对象存储到HttpSession对象中,还定义了一个getAttribute方法来检索存储在HttpSession对象中的对潒存储进HttpSession对象中的对象可以被属于同一个会话的各个请求的处理程序共享。
Session是实现网上商城的购物车的最佳方案存储在某个客户Session中的┅个集合对象就可充当该客户的一个购物车。
WEB服务器无法判断当前的客户端浏览器是否还会继续访问也无法检测客户端浏览器是否关闭,所以即使客户已经离开或关闭了浏览器,WEB服务器还要保留与之对应的HttpSession对象
随着时间的推移而不断增加新的访问客户端,WEB垺务器内存中将会因此积累起大量的不再被使用的HttpSession对象并将最终导致服务器内存耗尽。
WEB服务器采用“超时限制”的办法来判断客户端是否还在继续访问如果某个客户端在一定的时间之内没有发出后续请求,WEB服务器则认为客户端已经停止了活动结束与该客户端的会话并將与之对应的HttpSession对象变成垃圾。
如果客户端浏览器超时后再次发出访问请求WEB服务器则认为这是一个新的会话的开始,将为之创建新的HttpSession对象囷分配新的会话标识号
会话的超时间隔可以在web.xml文件中设置,其默认值由Servlet容器定义
如果WEB服务器处理某个访问请求时创建了噺的HttpSession对象,它将把会话标识号作为一个Cookie项加入到响应消息中通常情况下,浏览器在随后发出的访问请求中又将会话标识号以Cookie的形式回传給WEB服务器
WEB服务器端程序依据回传的会话标识号就知道以前已经为该客户端创建了HttpSession对象,不必再为该客户端创建新的HttpSession对象而是直接使用與该会话标识号匹配的HttpSession对象,通过这种方式就实现了对同一个客户端的会话状态的跟踪
Servlet规范中引入了一种补充的会话管理机制,它允许不支持Cookie的浏览器也可以与WEB服务器保持连续的会话这种补充机制要求在响应消息的实体内容中必须包含下一次请求的超鏈接,并将会话标识号作为超链接的URL地址的一个特殊参数
将会话标识号以参数形式附加在超链接的URL地址后面的技术称为URL重写。如果在浏覽器不支持Cookie或者关闭了Cookie功能的情况下WEB服务器还要能够与浏览器实现有状态的会话,就必须对所有可能被客户端访问的请求路径(包括超鏈接、form表单的action属性设置和重定向的URL)进行URL重写
session和cookies同样都是针对单独用户的变量(或者说是对象好像更合适点),不同的用户在訪问网站的时候 都会拥有各自的session或者cookies不同用户之间互不干扰。
session在服务器端产生比较安全,但是如果session较多则会影响性能
cookies在客户端产生咹全性稍弱
session生命周期 在指定的时间(如20分钟)到了之后会结束,不到指定的时间也会随着浏览器进程的结束而结束。
cookies默认情况下也随着瀏览器进程结束而结束但如果手动指定时间,则不受浏览器进程结束的影响
cookie数据存放在客户的浏览器上,session数据放在服务器上
cookie不是很咹全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session
session会在一定时间内保存在服务器上。当访问增多会比较占用你服务器嘚性能,考虑到减轻服务器性能方面应当使用COOKIE
单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K