http协议有http0.9,http1.0,http1.1和http2三个版本,但是现在浏览器使用的是http1.1的标准,本篇文章着重介绍关于http1.1的版本,同时穿插了解一下http2的一些新特性。
一 介绍
介绍不多说,HTTP是Hyper Text Transfer Protocol(超文本协议),是一个基于TCP/IP的应用层协议,主要用于从web服务器传输超文本到本地的浏览器的一个传输协议,由请求和响应构成,是一个标准的客户端服务器模型。
这里简要的介绍下http和https的区别:https协议是一个承载在SSL+TLS上,基于http和ssl构建的,其与http最大的区别就是其的安全性,而且其使用的是不一样的连接方式,用的端口也不一样(443,http是80),另外由于其确保安全性,那么https就需要进行与服务器的还密钥和确认加密算法的需要,这样的话跟服务器进行握手的次数就增多,影响性能且繁琐。
二 http的主要特点
1 支持客户端/服务器模式
2 简单快速:客户端向服务器请求服务的适合,只需要传输方法和路径。请求的常用方法有GET、HEAD、POST。由于每一种http协议都简单,使得http服务器的程序规模小,则通信速度很快
3 灵活:http允许传输任意类型的数据对象,正在传输的类型由请求头部的Content-Type加以标注
4 HTTP 0.9和1.0使用非持续连接:限制每次连接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。HTTP 1.1使用持续连接:不必为每个web对象创建一个新的连接,一个连接可以传送多个对象(这个关联到头部信息的Connection进行控制)
5 http是无状态协议。无状态指的是对于事物处理没有记忆能力,缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
(无状态协议:协议的状态是指下一次传输可以“记住”这次传输信息的能力。http不会为了下一次连接维护这次连接所传输的信息的,为了保证服务器的内存。
举例:比如客户获得一张网页之后关闭浏览器,然后再一次启动浏览器,再登陆该网站,但是服务器并不知道客户关闭了一次浏览器。由于Web服务器要面对很多浏览器的并发访问,为了提高Web服务器对并发访问的处理能力,在设计HTTP协议时规定Web服务器发送HTTP应答报文和文档时,不保存发出请求的Web浏览器进程的任何状态信息。这有可能出现一个浏览器在短短几秒之内两次访问同一对象时,服务器进程不会因为已经给它发过应答报文而不接受第二期服务请求。由于Web服务器不保存发送请求的Web浏览器进程的任何信息,因此HTTP协议属于无状态协议(Stateless Protocol)
)
HTTP协议是无状态的和Connection: keep-alive的区别:
HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。
从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。
1.1 版还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。
举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
三 工作流程
一次http操作称之为一次事物,工作过程可分为四步:
1)首先客户机与服务器需要建立连接。只要点击某个超链接,HTTP工作开始(建立连接)
2)之后,客户机发送请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号、后边是MIME信息包括请求修饰符、客户机信息和可能的内容。(发送请求)
3)服务器接收到请求之后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、后边是MIME信息包括请求修饰符、客户机信息和可能的内容。(响应请求)
4)客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接(断开连接)
上述过程有可能是客户机经过了代理服务器才到达的web服务器的
由于HTTP是基于传输层的TCP/IP协议的,TCP是一个端到端的面向连接的协议。所谓的端到端可以理解为进程到进程之间的通信,故HTTP在开始传输之前需建立TCP连接,TCP连接的过程需要所谓的“三次握手”,如图。连接之后就可以进行传输了,HTTP在传输完成之间不会断开TCP连接,在HTTP1.1中(通过Connection头设置)这是默认的行为
四 URL详解
URL:统一资源定位符,是URI(统一资源标识符)的一种,用于描述一个网络上的资源, 基本格式如下:schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]
scheme 指定低层使用的协议(例如:http, https, ftp)
host HTTP服务器的IP地址或者域名
“:”后的是端口,默认是80
path:是访问资源的路径
“;”后面的是url-params:URL参数,可以用作一个缓存的标识(session id)
query-string:发送给http服务器的数据,也可以说是查询参数,用&符号分隔
“#”后面的是锚
五 请求消息
5.1 请求的消息格式如下:
1)请求行,如GET /images/logo.gif HTTP/1.1,表示从/images目录下请求logo.gif这个文件,使用的是get方法,协议版本是http1.1
2)请求头,如Accept-Language: en
3)空行
4)可选的消息体
请求行和标题必须以回车换行作为结尾,空行中必定只有回车换行
5.2 请求方法
前面三个是http0.9和http1.0协议就已经有的,后面五个是http1.1之后加的
GET:向特定的资源发送请求
POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据包含在请求中,POST请求可能会导致新的资源建立和/或者已有资源的修改
HEAD:向服务器索要与GET请求相一致的响应,但是响应体不会被返回。这一方法可以在不必传输整个响应内容的情况下,就可以获取包含在响应消息头中的元信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新(那么主要 用于响应头信息的获取)
PUT:向制定资源位置上传其最新的内容
OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法。
DELETE:请求服务器删除Request-URI所标识的资源
TRACE:回显服务器收到的请求,用于测试或诊断
CONNECT:http1.1协议种预留给能够将连接改为管道方式的代理服务器
PATCH:用来将局部修改应用于某一资源,添加于规范RFC5789。
总结就是:GET方法用于在服务器中获取数据,POST方法是在服务器中修改资源数据,PUT是用于上传数据,DELETE是在服务器中删除资源,HEAD是获取响应头信息
GET和POST的区别:
1)提交的数据位置不同,GET是在URL之后,而POST是在HTTP包的body中
2)GET提交的数据大小有限制,最多有1024字节,主要是浏览器对URL的长度有限制,POST提交的数据没有限制
3)POST较GET安全,因为GET会将一些信息暴露在URL上,对于提交的数据都会显示在URL上,若页面可以缓存或者其他人可以访问,则可从历史记录获取这个用户账号密码什么的资料
4)GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值。
六 响应消息
客户端向服务器发送一个请求,服务器以一个状态行作为响应,响应的内容包括:消息协议的版本、成功或者错误编码、服务器信息、实体元信息以及必要的实体内容。根据响应类别的类别,服务器响应里可以含实体内容,但不是所有的响应都有实体内容。
格式:
http协议版本 空格 状态码 空格 Reason-Phrase 回车换行(Reason-Phrase是个简单的文本描述),如
七 http的状态响应码
1XX(信息类): 表示接收到请求并继续处理
2XX(响应成功):表示动作被成功接收,理解和接收
关注200:表明该请求被成功地完成,所请求的资源发送回客户端
3XX(重定向):为了完成指定的动作,必须接受进一步处理
关注304:自从上次请求后,请求的网页未修改过,服务器返回此响应时,不会返回网页内容,代表上次的文档已经被缓存了,还可以继续使用
4XX(客户端错误类):请求包含错误语法或不能正确执行
关注404:一个404错误表明可连接服务器,但服务器无法取得所请求的网页,请求资源不存在。eg:输入了错误的URL
5XX(服务器端错误类):服务器不能正确执行一个正确的请求
八 头部信息
8.1 HTTP常见的请求头
If-Modified-Since:把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。(这与对比缓存有关,后文会讲到,相对的是响应头的Last-Modified)
If-None-Match:If-None-Match和ETag一起工作,工作原理是在HTTP响应头中添加ETag信息。 当用户再次请求该资源时,将在HTTP请求头中加入If-None-Match信息(ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。否则将返回200状态和新的资源和Etag(这也与对比缓存有关,且优先级高于上面的If-Modified-Since/Last-Modified对)
Cache-Control:指定请求和响应遵循的缓存机制。缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程)。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage。(请求头和响应头中都有,关于强制缓存的)
Cache-Control:Public 客户端和服务器都可缓存
Cache-Control:Private 客户端可缓存
Cache-Control:no-cache 需要使用对比缓存来验证缓存数据
Cache-Control:no-store 所有内容都不会缓存,强制缓存,对比缓存都不会触发
Cache-Control:max-age 缓存的内容将在 xxx 秒后失效。
Cache-Control:min-fresh 指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
Cache-Control:max-stale 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
Accept:浏览器端可以接受的MIME类型。例如:Accept: text/html 代表浏览器可以接受服务器回发的类型为 text/html 也就是我们常说的html文档
Accept-Encoding:浏览器申明自己可接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)
Accept-Language:浏览器申明自己接收的语言。语言跟字符集的区别:中文是语言,中文有多种字符集,比如big5,gb2312,gbk等等
Accept-Charset:浏览器可接受的字符集
User-Agent:告诉HTTP服务器,客户端使用的操作系统和浏览器的名称和版本
Content-Type:例如:Content-Type: application/x-www-form-urlencoded。
Connection:例如:
Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。HTTP 1.1默认进行持久连接。利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。
Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接。
Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面
Host:(发送请求时,该头域是必需的)主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的(http1.1协议种必须包含)
例如: 我们在浏览器中输入:http://www.guet.edu.cn/index.html,浏览器发送的请求消息中,就会包含Host请求头域:Host:http://www.guet.edu.cn,此处使用缺省端口号80,若指定了端口号,则变成:Host:指定端口号
Cookie:最重要的请求头之一, 将cookie的值发送给HTTP服务器
Content-Length:表示请求消息正文的长度
Authorization:授权信息
8.2 HTTP常见的响应头
Allow:服务器支持哪些请求方法(如GET、POST等)
Date:表示消息发送的时间,时间的描述格式由rfc822定义。
Expires:指明应该在什么时候认为文档已经过期,从而不再缓存它,重新从服务器获取,会更新缓存
P3P:用于跨域设置Cookie, 这样可以解决iframe跨域访问cookie的问题
Set-Cookie:非常重要的header, 用于把cookie发送到客户端浏览器,每一个写入cookie都会生成一个Set-Cookie。
例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com
ETag:和If-None-Match 配合使用。
Last-Modified:用于指示资源的最后修改日期和时间。Last-Modified也可用setDateHeader方法来设置。
Content-Type:WEB服务器告诉浏览器自己响应的对象的类型和字符集,
例如:Content-Type: text/html;charset=utf-8
Content-Length:指明实体正文的长度,以字节方式存储的十进制数字来表示
Content-Encoding:WEB服务器表明自己使用了什么压缩方法(gzip,deflate)压缩响应中的对象
Content-Range:用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度
Content-Language:WEB服务器告诉浏览器自己响应的对象所用的自然语言
Connection:
例如:Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接。
Location:用于重定向一个新的位置,包含新的URL地址
Refresh:表示浏览器应该在多少时间之后刷新文档,以秒计
摘抄于:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html
九 HTTP缓存机制
WEB缓存(cache)位于Web服务器和客户端之间。
缓存会根据请求保存输出内容的副本,例如html页面,图片,文件,当下一个请求来到的时候:如果是相同的URL,缓存直接使用副本响应访问请求,而不是向源服务器再次发送请求。
HTTP协议定义了相关的消息头来使WEB缓存尽可能好的工作
9.1 缓存的优点
减少相应延迟:因为请求从缓存服务器(离客户端更近)而不是源服务器被相应,这个过程耗时更少,让web服务器看上去相应更快。
减少网络带宽消耗:当副本被重用时会减低客户端的带宽消耗;客户可以节省带宽费用,控制带宽的需求的增长并更易于管理。
9.2 http报文中跟缓存有关的头部字段
为了对以下能用到的一些头部信息能有个大致了解,介绍以下与缓存有关的头部字段
1. 通用首部字段(就是请求报文和响应报文都能用上的字段)
2. 请求首部字段
3. 响应首部字段
4. 实体首部字段
9.3 缓存方式
缓存实际上就是根据一些策略规则来决定是否使用浏览器中的一些存储的信息,这个缓存信息可以认为是浏览器中有存在的一个缓存数据库(也可以称为本地缓存)
根据是否需要重新向服务器发起请求来分类,可分为两大类(强制缓存、对比缓存)
强制类型不需要向服务器发起请求,对比缓存需要向服务器发起请求
9.3.1 强制缓存
已经具有缓存数据的时候,并且缓存时间未过期的话,使用强制缓存
http1.0的强制缓存是有两个字段来进行,Pragma(表示禁用缓存)和Expires(启用缓存和定义缓存时间)。同时使用的话,Pragma优先级会较高,但是响应报文中Expires所定义的缓存时间是相对服务器上的时间而言的,如果客户端上的时间跟服务器上的时间不一致(特别是用户修改了自己电脑的系统时间),那缓存时间可能就没啥意义了,为了解决这个问题,http1.1使用的是新字段:Cache-Control(重点掌握,以此为基准)
注意:为了做http协议的向下兼容,你还是可以看到很多网站依旧会带上这两个字段,实际上是可抛弃的两个字段了
Cache-Control
使用方法: "Cache-Control":"cache-directive"
作为请求头部的时候,cache-directive的可选值有
作为响应首部时,cache-directive 的可选值有:
实际重点关注五个值private、public、no-cache、max-age,no-store,默认为private
private:客户端可以缓存
public:客户端和代理服务器都可缓存(前端的同学,可以认为public和private是一样的)
max-age=xxx:缓存的内容将在 xxx 秒后失效
no-cache:需要使用对比缓存来验证缓存数据
no-store:所有内容都不会缓存,强制缓存,对比缓存都不会触发
举个例子:
图中Cache-Control仅指定了max-age,所以默认为private,缓存时间为31536000秒(365天)
也就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用
9.3.2 对比缓存
对比缓存:即需要进行比较判断是否可以使用缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中。再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据
对比缓存解决的问题:缓存时间过期,但是服务器却没有更新这个资源,此时客户端再次请求服务器把这个资源重新发过来的话,很浪费带宽和时间。对比缓存就是让服务器知道客户端现在存有的缓存文件,其实跟自己所有的文件是一致的,让客户端直接使用自己缓存的即可,提高了缓存的复用率
对比缓存是根据请求头部和响应头部的缓存标识进行判断的
对比缓存使用的缓存标识字段
Last-Modified / If-Modified-Since
Last-Modified:
服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:
再次请求服务器时,通过此字段通知服务器上次请求时,服务器返回的资源最后修改时间。
服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。
若资源的最后修改时间大于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;
若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
Last-Modified 说好却也不是特别好,因为如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)
ETag / If-None-Match(优先级高于Last-Modified / If-Modified-Since)
为了解决上述Last-Modified可能存在的不准确的问题,Http1.1还推出了 ETag 实体首部字段。
Etag可以理解成一个服务器用加密算法计算出来的唯一标识符,用来标识一个资源的,在客户端第一次请求的时候服务器会随着数据一起传给客户端,客户端会保留该 ETag 字段,并在下一次请求时将其一并带过去给服务器。服务器只需要比较客户端传来的ETag跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了
Etag:
服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。
If-None-Match:
再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。
服务器收到请求后发现有头If-None-Match 则与被请求资源的唯一标识进行比对,
不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;
相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
注意:如果同时存在两对字段,需要都通过才能使用缓存
总结
对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在时间内,执行比较缓存策略。
对于比较缓存,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。
浏览器第一次请求:
浏览器再次请求时:
摘抄于:http://www.cnblogs.com/vajoy/p/5341664.html、http://www.cnblogs.com/chenqf/p/6386163.html
十 解决HTTP无状态的问题
10.1 通过cookies保存状态信息
cookies实际上是一个保存在客户端上的,网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密),Cookie就是服务器暂存放在你的电脑里的资料(.txt格式的文本文件),通过在HTTP传输中的状态好让服务器用来辨认你的计算机。当你在浏览网站的时候,Web服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择都记录下来。
通过Cookies,服务器就可以清楚的知道请求2和请求1来自同一个客户端。
10.2 通过session保存状态信息
Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为 session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个 session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存
Session的实现方式:
1、使用Cookie来实现
服务器给每个Session分配一个唯一的JSESSIONID,并通过Cookie发送给客户端。
当客户端发起新的请求的时候,将在Cookie头中携带这个JSESSIONID。这样服务器能够找到这个客户端对应的Session。
2、使用URL回写来实现
URL回写是指服务器在发送给浏览器页面的所有链接中都携带JSESSIONID的参数,这样客户端点击任何一个链接都会把JSESSIONID带会服务器。如果直接在浏览器输入服务端资源的url来请求该资源,那么Session是匹配不到的。
Tomcat对Session的实现,是一开始同时使用Cookie和URL回写机制,如果发现客户端支持Cookie,就继续使用Cookie,停止使用URL回写。如果发现Cookie被禁用,就一直使用URL回写。jsp开发处理到Session的时候,对页面中的链接记得使用response.encodeURL() 。
10.3、通过表单变量保持状态
除了Cookies之外,还可以使用表单变量来保持状态,比如Asp.net就通过一个叫ViewState的Input=“hidden”的框来保持状态,比如:
这个原理和Cookies大同小异,只是每次请求和响应所附带的信息变成了表单变量。
10.4、通过QueryString保持状态
QueryString通过将信息保存在所请求地址的末尾来向服务器传送信息,通常和表单结合使用,一个典型的QueryString比如:www.xxx.com/xxx.aspx?var1=value&var2=value2
注意:这里说一点自己的见解,保持状态我感觉是服务器对某个状态进行标识,这样子其实是很像session机制的,具体看下面
十一 cookies与session
11.1 含义
cookie机制
Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie规范。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies 。
具体来说cookie机制采用的是在客户端保持状态的方案。它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持。cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力。
正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript也可以生成cookie。而cookie的使用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。
cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。(故也有内存cookie和硬盘cookie之分)
而session机制采用的是一种在服务器端保持状态的解决方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的。而session提供了方便管理全局变量的方式
session是针对每一个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪个用户session变量,这个值是通过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器。
就安全性来说:当你访问一个使用session 的站点,同时在自己机子上建立一个cookie,建议在服务器端的session机制更安全些,因为它不会任意读取客户存储的信息
session机制
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。
保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。
经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。
11.2 作用
都是可以进行保持状态的一种机制
11.3 区别
11.3.1 存取方式的不同
cookie只能存储ASCII字符串
session可以存储任意类型的数据
11.3.2 隐私策略的不同
Cookie存储在客户端阅读器中,对客户端是可见的,客户端的一些程序可能会窥探、复制以至修正Cookie中的内容。而Session存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险。
假如选用Cookie,比较好的方法是,敏感的信息如账号密码等尽量不要写到Cookie中。最好是像Google、Baidu那样将Cookie信息加密,提交到服务器后再进行解密,保证Cookie中的信息只要本人能读得懂。而假如选择Session就省事多了,反正是放在服务器上,Session里任何隐私都能够有效的保护
11.3.3 有效期上的不同
使用过Google的人都晓得,假如登录过Google,则Google的登录信息长期有效。用户不用每次访问都重新登录,Google会持久地记载该用户的登录信息。要到达这种效果,运用Cookie会是比较好的选择。只需要设置Cookie的过期时间属性为一个很大很大的数字。
由于Session依赖于名为JSESSIONID的Cookie,而Cookie JSESSIONID的过期时间默许为–1,只需关闭了阅读器该Session就会失效,因而Session不能完成信息永世有效的效果。运用URL地址重写也不能完成。而且假如设置Session的超时时间过长,服务器累计的Session就会越多,越容易招致内存溢出
11.3.4 服务器压力不同
Session是保管在服务器端的,每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存。因而像Google、Baidu、Sina这样并发访问量极高的网站,是不太可能运用Session来追踪客户会话的。
而Cookie保管在客户端,不占用服务器资源。假如并发阅读的用户十分多,Cookie是很好的选择。关于Google、Baidu、Sina来说,Cookie或许是唯一的选择。
11.3.5 浏览器支持的不同
Cookie是需要客户端浏览器支持的。假如客户端禁用了Cookie,或者不支持Cookie,则会话跟踪会失效。关于WAP上的应用,常规的Cookie就派不上用场了。
假如客户端浏览器不支持Cookie,需要运用Session以及URL地址重写。需要注意的是一切的用到Session程序的URL都要进行URL地址重写,否则Session会话跟踪还会失效。关于WAP应用来说,Session+URL地址重写或许是它唯一的选择。
假如客户端支持Cookie,则Cookie既能够设为本浏览器窗口以及子窗口内有效(把过期时间设为–1),也能够设为一切阅读器窗口内有效(把过期时间设为某个大于0的整数)。但Session只能在本阅读器窗口以及其子窗口内有效。假如两个浏览器窗口互不相干,它们将运用两个不同的Session。(IE8下不同窗口Session相干)
11.3.6 跨域支持上的不同
Cookie支持跨域名访问,例如将domain属性设置为“.biaodianfu.com”,则以“.biaodianfu.com”为后缀的一切域名均能够访问该Cookie。跨域名Cookie如今被普遍用在网络中,例如Google、Baidu、Sina等。而Session则不会支持跨域名访问。Session仅在他所在的域名内有效。
仅运用Cookie或者仅运用Session可能完成不了理想的效果。这时应该尝试一下同时运用Cookie与Session。Cookie与Session的搭配运用在实践项目中会完成很多意想不到的效果
11.4 联系
客户第一次发送请求给服务器,此时服务器产生一个唯一的sessionID,并返回给客户端(通过cookie),保存于客户端的内存中,并与一个浏览器窗口对应着,由于HTTP协议的特性,这一次连接就断开了。
以后此客户端再发送请求给服务器的时候,就会在请求request中携带cookie,由于cookie中有sessionID,所以服务器就知道这是刚才那个客户端。
也就是说cookie可以存储sessionid的一种标识。
摘抄来自于:http://blog.csdn.net/weixin_37196194/article/details/55806366
十二 http2的新特性
2015年发布的http2
12.1 二进制协议
HTTP/1.1 版的头信息肯定是文本(ASCII编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。
二进制协议的一个好处是,可以定义额外的帧。HTTP/2 定义了近十种帧,为将来的高级应用打好了基础。如果使用文本实现这种功能,解析数据将会变得非常麻烦,二进制解析则方便得多
12.2 多工
HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了"队头堵塞"。(队头阻塞意思是客户端或者服务器发送消息的时候,如果某条数据太大,那么需要的时间就要很长,后面等待发送的就会有很多,造成堵塞)
举例来说,在一个TCP连接里面,服务器同时收到了A请求和B请求,于是先回应A请求,结果发现处理过程非常耗时,于是就发送A请求已经处理好的部分, 接着回应B请求,完成后,再发送A请求剩下的部分。
这样双向的、实时的通信,就叫做多工(Multiplexing)
12.3 数据包
由于多工的特性存在,http2的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。
HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。
数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。1.1版取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。
客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。
12.4 头信息压缩
HTTP 协议不带有状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如Cookie和User Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。
HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。一方面,头信息使用gzip或compress压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
12.5 服务器推送
HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)。
常见场景是客户端请求一个网页,这个网页里面包含很多静态资源。正常情况下,客户端必须收到网页后,解析HTML源码,发现有静态资源,再发出静态资源请求。其实,服务器可以预期到客户端请求网页后,很可能会再请求静态资源,所以就主动把这些静态资源随着网页一起发给客户端了。
这里可以去搜搜看阮一峰的网络日志中关于http协议这一篇,写的简短又有内涵