HTTP
万维网
蒂姆·伯纳斯-李现在是万维网联盟(W3C)的领导人,这个组织的作用是使计算机能够在万维网上不同形式的信息间更有效的储存和通信。
万维网标准
万维网的核心部分是由三个标准构成的:
- 统一资源标识符(URI),这是一个世界通用的负责给万维网上例如网页这样的资源定位的系统
- 超文本传送协议(HTTP),它负责规定浏览器和服务器怎样互相交流
- 超文本标记语言(HTML),作用是定义超文本 文档的结构和格式
万维网的工作原理
- 首先在浏览器上键入想访问网页的统一资源定位符(Uniform Resource Locator),或者通过超链接方式链接到那个网页或网络资源。这之后的工作首先是URL 的服务器名部分,被名为域名系统的分布于全球的因特网数据库解析,并根据解析结果决定进入哪一个IP地址(IP address)
- 接下来为所要访问的网页,向在那个IP地址工作的服务器发送一个HTTP请求。在通常情况下,HTML文本、图片和构成该网页的一切其他文件很快会被逐一请求并发送回用户
- 网络浏览器接下来的工作是把HTML、CSS和其他接受到的文件所描述的内容,加上图像、链接和其他必须的资源,显示给用户。这些就构成了所看到的“网页”
- 大多数的网页自身包含有超链接指向其他相关网页,可能还有下载、源文献、定义和其他网络资源。像这样通过超链接,把有用的相关资源组织在一起的集合,就形成了一个所谓的信息的“网”
Web
Web浏览器
Web浏览器的基本功能是导航和浏览:
- 第一个图形化界面的Web浏览器是Mosaic
- 导航是根据给定的超链接在Web中穿梭航行并从Web 服务器上获取Web页
- 浏览是解释和显示Web页。导航是执行HTTP协议;浏览是解释HTML语言
- 为方便用户,大多数浏览器都提供一些标准的控制按钮;为改进性能,有些浏览器把已访问过的Web页在本机缓存
- 任何Web浏览器都可以让用户打开一个URL
Web服务器
Web服务器也称为WWW(World Wide Web)服务器,主要功能是提供网上信息浏览服务。WWW 是 Internet 的多媒体信息查询工具,是Internet 上近年才发展起来的服务,也是发展最快和目前用的最广泛的服务。
最常用的Web服务器:
- Apache软件基金会的Apache HTTP服务器
- Microsoft的Internet Information Server(IIS)
- Google的Google Web Server
- nginx公司的nginx
- lighttpd公司的lighttpd
Web服务器的内容
- 应用层使用HTTP协议
- HTML文档格式
- 浏览器统一资源定位器(URL)
- 服务器使用HTTP(超文本传输协议)与客户机浏览器进行信息交流,这就是人们常把它们称为HTTP服务器的原因
Web中的MIME
MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展 )在Web中用于指定大量数据的类型(如文件或Web页面)。MIME使用户可发送多种格式的数据,而不单单是文本数据。由于使用了MIME,用户可以发送和接收包含非ASCII码数据如声音、视频、图像应用等的页面。当Web浏览器与服务器建立连接时,它们协商MIME类型。浏览器向服务器发送它所能接收的MIME类型,这部分信息位于请求头中。服务器通知客户方它发送的数据包含的MIME类型
Web缓存技术
- 缓存可以在不同的地方实现:
- 用户的浏览器可以缓存最近访问过的页
- 代理缓存
- 缓存Web页的能力
- HTTP 使之变得容易
- 关键是缓存必须确保不会响应过期的页
安全信息机制
- 安全套接层(Secure Socket Layer,SSL)
- 加强连接的安全
- 基于SSL的服务器用https取代http
- 安全HTTP(S-HTTP)
- 加强发送信息的安全
HTTP协议
HTTP协议的几个重要概念
- 连接(Connection):一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间
- 消息(Message):HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输
- 请求(Request):一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标识符和协议的版本号
- 响应(Response):一个从服务器返回的信息包括HTTP协议的版本号、请求的状态(例如“成功”或“没找到”)和文档的MIME类型
- 资源(Resource):由URI标识的网络数据对象或服务
- 实体(Entity):数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息和实体的本身内容
- 客户机(Client):一个为发送请求目的而建立连接的应用程序
- 用户代理(User agent):初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具
- 服务器(Server):一个接受连接并对请求返回信息的应用程序
- 源服务器(Origin server):是一个给定资源可以在其上驻留或被创建的服务器
- 代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过在内部可能的翻译并传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求
- 网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不 同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发 出请求的客户机并没有意识到它在同网关打交道。网关经常作为通过防 火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些 存储在非HTTP系统中的资源
- 通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时经常使用通道
- 缓存(Cache):反映信息的局域存储
超文本传输协议HTTP
- HTTP 0.9 1991
- HTTP 1.0 RFC 1945 1996
- HTTP 1.1
- HTTP/2
- HTTP/3 draft-ietf-quic-http-27 2020
超文本传输协议HTTP(一)
- HTTP协议使Web服务器和浏览器可以通过Web交换数据。它是一种请求/响应协议,即服务器等待并响应客户方请求。请求与响应以ASCII编码的明文形式交换
- HTTP是一种无状态协议,它不维护连接的状态信息。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传, 这样可能导致每次连接传送的数据量增大。另一方面, 在服务器不需要先前信息时它的应答就较快
- HTTP专用于访问网络上的分布式超媒体信息。它可用 于基本的通信目的,例如网络文件、邮件或新闻的传送
超文本传输协议HTTP(二)
- 被访问的超媒体信息称为资源,由明确的统一资源标识符(URI)统一编址
- HTTP连接建立在每一对客户和服务器之间。客户发出的请求,被服务器接受、处理并应答。服务器可以是源服务器,也可以是代理服务器
客户/服务器传输过程
- 浏览器与服务器建立连接
- 与服务器建立连接,就是与SOCKET建立连接,因此要指定机器名称、资源名称和端口号,可以通过URL来提供这些信息。URL 的格式为:HTTP://<IP地址>/[端口号]/[路径][?<查询信息>]
- 资源的缺省值是INDEX或DEFAULT,端口号缺省为80
- 浏览器向服务器请求文档
- 请求信息包括希望返回的文件名和客户机信息。客户机信息以请求头发送给服务器,请求头包括HTTP请求方法和头字段,HTTP 方法常用的有GET、HEAD、POST
- 服务器响应浏览器请求
- 服务器收到一个请求,就会立刻解释请求中所用到的方法,并开始处理应答。服务器的应答消息也包含头字段形式的报文信息
- 断开连接
超文本传输协议HTTP(三)
- 请求或响应报文头有零个、一个或多个头字段,构造成通用、请求、响应和实体字段
- 通用字段对请求消息和响应消息都适用
- 请求字段给出了有关请求和客户本身的额外信息
- 响应字段传送有关服务器和进一步访问被请求资源的信息
超文本传输协议HTTP(四)
消息体(如果有的话)携带了一个资源实体。资源一般位于某个源服务器上,它可以是任何超媒体信息对象,例如静态HTML页面;或者是某个服务, 例如产生HTML页面的公共网关接口(CGI)程序。这两种情况下,HTML页面如果由客户与服务器之间的消息体传送,则称为(资源)实体。
超文本传输协议HTTP(五)
HTTP请求
- GET / HTTP/1.1
Host: www.hust.edu.cn - OPTIONS
- GET
- HEAD
- POST
- PUT
- DELETE
- TRACE
超文本传输协议HTTP(六)
响应请求
- 状态行
- HTTP/[HTTP Version] [Status Code] [Space]
- 状态代码
- 信息 1××
- 成功 2××
- 重定向 3××
- 客户机错误 4××
- 服务器错误 5××
HTTP
HTTP1.1改进
- HTTP版本1.0为从服务器取出的每个数据项建立一条单独的TCP连接
- 最新的HTTP版本1.1的最重要改进是它采用持续连接,还能处理MIME类型的消息,定义了一个复杂的高速缓存
持续连接(persistent-connection)
- 优点:
- 可以明显地消除连接建立的开销,减轻服务器的负载
- 客户可以在一个TCP连接上发送大量的请求消息,TCP的拥塞窗口机制可以更高效地工作
- 缺点:
- 客户和服务器都不知道将一个TCP连接保持多久
- 解决措施:当服务器在一条连接上有一段时间没有收到请 求,它就将这条连接超时,关闭连接;或者客户和服务器 都必须注意另一端是否决定关闭连接,并以此为信号也关 闭己端的连接(双方都必须关闭连接之后连接才完全结束)
Cookie
- 指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。定义于RFC2109。为网景公司的前雇员Lou Montulli在1993年3月所发明
- Cookie可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了(当然,不排除用户手工删除Cookie)。而且还有一些Cookie在用户退出会话的时候就被删除了,这样可以有效保护个人隐私
- 正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie
- Cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器
- Cookie的内容主要包括:名字,值,过期时间,路径和域。
- 其中域可以指定某一个域比如.google.com
- 路径就是跟在域名后面的URL路径,比如/或者/foo等等
- 路径与域合在一起就构成了cookie的作用范围
- 如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间
Session
- Session是指一类用来在客户端与服务器之间保持状态的解决方案
- 有时候session也用来指这种解决方案的存储结构,如“把xxx保存在session里”
- 由于各种用于web开发的语言在一定程度上都提供了对这种解决方案的支持,所以在某种特定语言的语境下,session也被用来指代该语言的解决方案,比如经常把Java里提供的javax.servlet.http.HttpSession简称为session
- cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案
- session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息
- 当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id 则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存
- 保存这个session id的方式可以采用cookie, 这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID,比如weblogic 对 于 web 应 用 程 序 生 成 的 cookie, JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!- 145788764,它的名字就是JSESSIONID
- 由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL 路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http:// /xxx;jsessionid=ByOK3vjFD75aPnrF 7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWp Bng!-145788764或者作为查询字符串附加在URL后面,表现形式为http:// /xxx?jsessionid=ByOK3vjFD75aPnr
F7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zW pBng!-145788764。另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如下面的表单
<form name="testform" action="/xxx">
<input type="text">
</form>
在被传递给客户端之前将被改写成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEb zWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
- 在谈论session机制的时候,常常听到这样一种误解“只要关闭浏览器,session就消失了”
- 对session来说,除非程序通知服务器删除一个session, 否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session
- 由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间
HTTP的发展
- HTTP发展中存在的问题
- 复杂性
- 可扩展性
- 性能
- 传输依赖性
- HTTP-NG的主题:模块化及功能增强
- WebMUX
- 二进制连接协议http://www.w3.org/Protocols/HTTP-NG/
- Mozilla官方安全博客日前刊文宣布了正式淘汰HTTP的方案。
- Mozilla称在经过热烈的讨论以后,Mozilla准备将继续向安全方向前进,并逐渐开始移除不安全的网站。要使用加密的HTTPS。
- Mozilla现在讨论的结果有两个:
- 设定一个日期,所有的新特性将只提供给HTTPS网站;
- HTTP网站将逐步被禁止访问浏览器功能设定,尤是那些与用户安全和隐私相关的功能
HTTP/2
传送数据大小和对象数量
- 当前互联网网站首页数据量下载很大,达到1.9M
- 更重要的是首页上的对象元素平均有100多个
- 这100多个对象必须抓取完毕后才能显示整个首页页面
- 网页包含许多不同的组件
- 标准的HTML
- 设计元素 CSS
- 客户端语言JavaScript
- 图像
- 视频
- Flash 动画
- 为了传输这些信息,浏览器不得不创建多个连接, 每个连接都包含头文件、目的和通讯包或通讯协 议的详细信息
延迟
- HTTP/1.1是对延迟非常敏感的,部分是因为HTTP Pipelining在面对大量并发用户时会显得力不从心, 在过去几年中带宽大量增加,但是我们没有看到页面延时以同样级别降低,高延时链接比如目前移动技术使得你即使拥有高速连接情况下也很难 获得好的快速Web体验
- 另外一个情况是,低延迟非常适合视频,比如视频会议、游戏和类似不是预先产生而是实时产生的流媒体或流数据
堵塞的原因
- HTTP Pipelining是一种这样的技术,当在等待上一个请求响应的时候发送另外一个请求,这好像你走入了超市的收银台前排队队列,你无法确切知道排在你前面的人能够快速付款购买完成,还是发生一堆恼人的烦事在那里纠缠不清,这就是堵塞的源头
- 所以,你得仔细地选择一个排队队伍,有时你相信你选择了一个正确的队伍,能够快速轮到你, 但是有时你不得不在几个队伍之间切换排队
克服延迟的办法
- Spriting
- Spriting 是一种前端页面的处理方式,将多个小图 片合成一张大图,然后,使用javascript或CSS在显示时将这张大图分割成多个小图,这样降低抓取多个小图造成的高延迟。当然这种办法也有缺点, 如果只要想显示一个或两个小图,而不是很多小 图都想显示,这样做就麻烦了
- Inlining
- Inlining内联是另外一个避免发送单独图像的方式, 使用CSS文件中嵌入的URL,优缺点和Spriting类似:
.icon1 {
background: url(data:image/png;base64,<data>) no-repeat;}
.icon2 {
background: url(data:image/png;base64,<data>) no-repeat;}
- Concatenation
- Concatenation串联类似前面两个技术,一个大型网站需要很多Javascript文件,前端工具会帮助开发者将这些小文件融入到一个大文件中,这样做的缺点是,当其中一个文件小修改时,整个文件都需要重新加载
- Sharding
- Sharding是将你的服务尽可能分离成不同的单独主机上,看上去很疯狂,但是其实很简单,HTTP 1.1规定一个客户端允许连接到每个主机最多两个,这样不违反规定的情况下,聪明的网站将使用两个主机名,能够降低页面的装载时间
- 不过,随着时间推移,规定中的限制已经去除,今天客户端可以用6-8个连接每个主机,但是使用这个技术实现大量连接还是有限制的。根据httparchive.org显示世界上大部分网站需要38个TCP连接来显示网站,这个数字还在缓慢增加。将资源或图片放在另外一个主机名中就不能使用任何cookie
SPDY
- SPDY协议是由Google开发的,使用SPDY 后的传输速度能够提高10个百分点,并且在某些情况下甚至能达到40%。SPDY已经被证明是一个可运行的方案
- SPDY 的成功使得互联网社区决定创建新的技术协议,这就是HTTP/2 的由来
为什么HTTP/2更好?
- 2015年5月,互联网工程任务组正式发布了HTTP/2规格,RFC编号为7540
- HTTP/2的改进之处包括更快的页面加载;更长久的连接;服务器推送,允许服务器主动向客户端推送消息;减少加密连接开销,改进性能;多路复用功能允许同时发送许多个请求。HTTP/2使用HTTP/1相同的API,开发者不需要改变应用程序代码就能更新库支持HTTP/2
- HTTP/2 加载网页速度更快、省时
Http/2
- Http/2 协议是一个二进制协议, 二进制更易于frame(帧/数据包)的实现,Http/2有十个不同frame 定义,其中两个最基础的对应于Http/1.1的是Data 数据和HEADER头部
- frame包含几个部分:类型Type, 长度Length, 标记Flags, 流标识Stream和frame payload有效载荷。
- 多路复用流Multiplexed stream
- Http/2连接可以承载数十或数百个流的复用,多路复用意味著来自很多流的数据包能够混合在一起通过同样连接传输
- 在HTTP/1中需要维持连接以便持续发送和接受数据,这导致数据拥挤和RTT浪费损耗,在HTTP/2中, 所有流都能时刻被切断提炼数据包
- 优先权和依赖
- 每个流都有自己的优先级别,会表明哪个流是最重要的,客户端会指定哪个流是最重要的,有一些依赖参数,这样一个流可以依赖另外一个流
- 优先级别可以在运行时动态改变,当用户滚动页面时,可以告诉浏览器哪个图像是最重要的,你也可以在一组流中进行优先筛选,能够突然抓住重点流
- 头部压缩
- HTTP是一个无态协议,也就是说,每个请求必须携带更多 细节,以便服务器能够识别从而服务这个请求,这些都无 需服务器自己保存太多信息以及先前请求的元数据信息, HTTP2没有改变这个范式。但是这种方式会产生重复信息, 当一个客户端向相同服务器请求许多资源时,像来自同一 个网页的图像,将会有大量的请求看上去几乎同样的,这 就需要压缩技术对付这种几乎相同的信息
- HTTPS和SPDY的压缩被发现容易导致BREACH4和CRIME攻击。因此压缩不是一个简单的课题,HPACK6是HTTP/2的头部压缩
- 随时复位
- HTTP/1.1一个缺点是当HTTP信息有一定长度大小数据传输时,你不能方便地随时停止它,中断TCP 连接的代价是昂贵的。使用HTTP/2的RST_STREAM 将能方便停止一个信息传输,启动新的信息,在不中断连接的情况下提高带宽利用效率
- 服务器端推送
- 客户端请求一个资源X,服务器端判断也许客户端还需要资源Z,在无需事先询问客户端情况下将资源Z推送到客户端,客户端接受到后,可以缓存起来以备后用
- 流量控制
- http/2 的每个独立流都有自己的流量控制flow controller,每个流两端都必须告诉对方自己有更 多空间适合数据存放,另外一端只能允许发送更 多数据直至流flow窗口被拓展,类似SSH工作风格, 只有DATA frame是流量控制的
- 下面这个发布在 HttpWatch 上的例子,显出出传输速度提高了近20%,而这仅仅是一次未完全优化的网页服务器测试