http协议概览

这里我只是对一些知识进行简单的整理,方便本身理解记忆,还有不少不完善的地方,更多细节,须要查看书籍或者其余文章javascript

http协议的发展过程

HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通讯格式,默认使用80端口。html

http/0.9
1991年发布,只有一个命令GET,协议规定,服务器只能回应HTML格式的字符串,不能回应别的格式。java


http/1.0
1996年5月发布,HTTP/1.0 版本发布,内容大大增长,首先,任何格式的内容均可以发送。这使得互联网不只能够传输文字,还能传输图像、视频、二进制文件。这为互联网的大发展奠基了基础。除了GET命令,还引入了POST命令和HEAD命令,丰富了浏览器与服务器的互动手段。node

HTTP请求和回应的格式也变了。除了数据部分,每次通讯都必须包括头信息(HTTP header),用来描述一些元数据。跨域

其余的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。浏览器

**缺点:**
  1. 每一个TCP链接只能发送一个请求。发送数据完毕,链接就关闭,若是还要请求其余资源,就必须再新建一个链接。
    TCP链接的新建成本很高,由于须要客户端和服务器三次握手,而且开始时发送速率较慢(slow start)。因此,HTTP 1.0版本的性能比较差。随着网页加载的外部资源愈来愈多,这个问题就愈发突出了。

    为了解决这个问题,有些浏览器在请求时,用缓存

  2. 列表项目

了一个非标准的Connection字段。安全

Connection: keep-alive

一个能够复用的TCP链接就创建了,直到客户端或服务器主动关闭链接。可是,这不是标准字段,不一样实现的行为可能不一致,所以不是根本的解决办法。

http/1.1
1997年1月发布,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到如今仍是最流行的版本。服务器

1.1 版的最大变化,就是引入了持久链接(persistent connection),即TCP链接默认不关闭,能够被多个请求复用,不用声明Connection: keep-alive。cookie

客户端和服务器发现对方一段时间没有活动,就能够主动关闭链接。不过,规范的作法是,客户端在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP链接。

1.1版还新增了许多动词方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。

**缺点**
  • 虽然1.1版容许复用TCP链接,可是同一个TCP链接里面,全部的数据通讯是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为"队头堵塞"(Head-of-line blocking)。

    为了不这个问题,只有两种方法:
    一是减小请求数;
    二是同时多开持久链接。这致使了不少的网页优化技巧,好比合并脚本和样式表、将图片嵌入CSS代码、域名分片(domain sharding)等等。若是HTTP协议设计得更好一些,这些额外的工做是能够避免的。


SPDY
2009年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。这个协议在Chrome浏览器上证实可行之后,就被看成 HTTP/2 的基础,主要特性都在 HTTP/2 之中获得继承。


HTTP/2
2015年,HTTP/2 发布。它不叫 HTTP/2.0,是由于标准委员会不打算再发布子版本了,下一个新版本将是 HTTP/3。

HTTP/1.1 版的头信息确定是文本(ASCII编码),数据体能够是文本,也能够是二进制。HTTP/2 则是一个完全的二进制协议

二进制协议的一个好处是,能够定义额外的帧。HTTP/2 定义了近十种帧,为未来的高级应用打好了基础。若是使用文本实现这种功能,解析数据将会变得很是麻烦,二进制解析则方便得多。

HTTP/2 复用TCP链接,在一个链接里,客户端和浏览器均可以同时发送多个请求或回应,并且不用按照顺序一一对应,这样就避免了"队头堵塞"。

HTTPS
HTTPS是HTTP协议的安全版本,HTTP协议的数据传输是明文的,是不安全的,HTTPS使用了SSL/TLS协议进行了加密处理。

http协议的特色

  • 无状态——每次HTTP请求都是独立的,任何两个请求之间没有什么必然的联系。可是在实际应用当中并非彻底这样的,引入了Cookie和Session机制来关联请求。
  • 无链接的——每次请求完成以后当即断开链接
  • 单向的应用层协议——通讯请求只能由客户端发起,服务端对请求作出应答处理。
  • 屡次请求—— 在客户端请求网页时多数状况下并非一次请求就能成功的,服务端首先是响应HTML页面,而后浏览器收到响应以后发现HTML页面还引用了其余的资源,例如,CSS,JS文件,图片等等,还会自动发送HTTP请求这些须要的资源。

如今的HTTP版本支持管道机制(即在同一个TCP链接里面,客户端能够同时发送多个请求),能够同时请求和响应多个请求,大大提升了效率。

http报文结构

clipboard.png

请求行

  • url —— Request URL
  • 请求方法 —— Request Method
  • 状态码 —— Status Code
  • 服务器地址 —— Remote Address

    在跨域拒绝时,多是method为options,状态码为404/405等(固然,实际上可能的组合有不少)的


**经常使用状态码:**
200——代表该请求被成功地完成,所请求的资源发送回客户端
304——自从上次请求后,请求的网页未修改过,请客户端使用本地缓存
400——客户端请求有错(譬如能够是安全模块拦截)
401——请求未经受权
403——禁止访问(譬如能够是未登陆时禁止)
404——资源未找到
500——服务器内部错误
503——服务不可用
...


**HTTP请求方法**
在HTTP1.1版本中支持GET、POST等近10种方法.

clipboard.png


通用首部字段

clipboard.png

clipboard.png

clipboard.png

clipboard.png

HTTP Cookie

本质上cookies就是http的一个扩展。有两个http头部是专门负责设置以及发送cookie的,它们分别是Set-Cookie以及Cookie。

HTTP Cookie(也叫Web Cookie或浏览器Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。一般,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登陆状态。Cookie使基于无状态的HTTP协议记录稳定的状态信息成为了可能。

Cookie主要用于如下三个方面:

  • 会话状态管理(如用户登陆状态、购物车、游戏分数或其它须要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

Cookie曾一度用于客户端数据的存储,因当时并无其它合适的存储办法而做为惟一的存储手段,但如今随着现代浏览器开始支持各类各样的存储方式,Cookie渐渐被淘汰。因为服务器指定Cookie后,浏览器的每次请求都会携带Cookie数据,会带来额外的性能开销(尤为是在移动环境下)。新的浏览器API已经容许开发者直接将数据存储到本地,如使用 Web storage API (本地存储和会话存储)或 IndexedDB 。

建立cookie
服务器收到HTTP请求时,服务器能够在响应头里面添加一个Set-Cookie选项。浏览器收到响应后一般会保存下Cookie,以后对该服务器每一次请求中都经过Cookie请求头部将Cookie信息发送给服务器。另外,Cookie的过时时间、域、路径、有效期、适用站点均可以根据须要来指定。

nodejs中服务端设置cookie的方法

request.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

cookie是保存在客户端中,按照客户端中存储的位置,可分为内存cookie和硬盘cookie。

内存cookie
cookie的生存时间是整个会话期间的话,浏览器会将cookie保存在内存中,浏览器关闭时就会自动清除这个cookie

硬盘cookie
就是cookie保存在客户端的硬盘中,浏览器关闭的话,该cookie也不会被清除,下次打开浏览器访问对应网站时,这个cookie就会自动再次发送到服务器端。

cookie不可跨域
不少网站都会使用Cookie。例如:Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?或者Google能不能修改Baidu颁发的Cookie呢?
案是否认的。Cookie具备不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操做Google的Cookie,而不能操做百度的Cookie。
Cookie在客户端是由浏览器来管理的。浏览器可以保证Google只会操做Google的Cookie而不会操做Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操做另外一个网站Cookie的依据是域名。Google与Baidu的域名不同,所以Google不能操做Baidu的Cookie。

同一个一级域名下的两个二级域名如www.helloweenvsfei.com和images.helloweenvsfei.com也不能交互使用Cookie,由于两者的域名并不严格相同。若是想全部helloweenvsfei.com名下的二级域名均可以使用该Cookie,须要设置Cookie的domain参数,例如:

Cookie cookie = new Cookie("time","20080808"); // 新建Cookie
cookie.setDomain(".helloweenvsfei.com"); // 设置域名
cookie.setPath("/"); // 设置路径
cookie.setMaxAge(Integer.MAX_VALUE); // 设置有效期
response.addCookie(cookie); // 输出到客户端

cookie的有效期
Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中经过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。 若是maxAge属性为正数,则表示该Cookie会在maxAge秒以后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。不管客户关闭了浏览器仍是电脑,只要还在maxAge秒以前,登陆网站时该Cookie仍然有效。

若是maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,所以关闭浏览器该Cookie就消失了。

注意:从客户端读取Cookie时,包括maxAge在内的其余属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过时。

Cookie的安全属性
HTTP协议不只是无状态的,并且是不安全的。使用HTTP协议的数据不通过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。若是不但愿Cookie在HTTP等非安全协议中传输,能够设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:

Cookie cookie = new Cookie("time", "20080808"); // 新建Cookie
cookie.setSecure(true); // 设置安全属性
response.addCookie(cookie); // 输出到客户端

提示:secure属性并不能对Cookie内容加密,于是不能保证绝对的安全性。若是须要高安全性,须要在程序中对Cookie内容加密、解密,以防泄密。

http session

session和cookie同样,都是用来记录http状态的一种机制,但不一样的是cookie存在于客户端,所携带的大小收到限制,而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。

一般session的建立须要依赖cookie,但cookie能够被人为的禁止,须要有其余的机制以便在cookie被禁止的时候可以把session id 传递回服务器,能够把session id直接附加在URL路径的后面

注意:在谈论session机制的时候,经常听到这样一种误解“只要关闭浏览器,session就消失了”。其实能够想象一下会员卡的例子,除非顾客主动对店家提出销卡,不然店家绝对不会轻易删除顾客的资料。对session来讲也是同样的,除非程序通知服务器删除一个session,不然服务器会一直保留,程序通常都是在用户作log off的时候发个指令去删除session。
然而浏览器历来不会主动在关闭以前通知服务器它将要关闭,所以服务器根本不会有机会知道浏览器已经关闭,之因此会有这种错觉,是大部分session机制都使用会话cookie来保存session id而关闭浏览器后这个session id就消失了,再次链接服务器时也就没法找到原来的session
若是服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然可以找到原来的session。

参考文章:
http://www.ruanyifeng.com/blo...
https://www.cnblogs.com/wxism...
https://developer.mozilla.org...
https://www.2cto.com/kf/20120...

相关文章
相关标签/搜索