Cookie、Session、HTTP、TCPIP梳理

Cookie、Session、HTTP、TCP/IP梳理

最近邹XX同学问了我一个问题:如何在一个Request请求中,向用户响应报文时给用户传递一个二进制文件?针对这个问题,我觉得有必要梳理一下:在浏览器输入地址按下回车之后都发生了什么?不会很深入,重点在说清楚流程,如有不对的地方,欢迎指正~~~

1、概述

那么在浏览器中输入地址(比如:www.baidu.com)之后按下回车到底发送了什么呢?

  • 简单来说就是这样:

    1. 浏览器访问DNS服务器,根据你输入的域名找到对应的IP地址(Web服务器IP)
    2. 浏览器与服务器端建立TCP连接,默认端口:80
    3. 浏览器将请求报文发送到服务器端,保持TCP连接并等待服务端响应
    4. 服务端接收到请求报文、处理,将响应内容通过TCP发往浏览器
    5. 关闭TCP连接
    6. 浏览器解析响应报文

HTTPS会更加复杂一点,客户端和服务前之间需要协商加密方式,验证证书等。具体验证过程参考

  • 更进一步来说是这样:

这里写图片描述

2、HTTP协议

2.1、概念

HTTP协议是HyperText Transfer Protocol(超文本传输协议)的简称,建立在TCP/IP协议之上,属于应用层协议。该协议不涉及数据传输,而是定义了数据传输规范(即:报文格式)。目前大多数网站使用的是HTTP 1.0版本,2.0版本正在推广中。HTTP协议主要的特点:

  • 支持C/S模式,B/S模式也是C/S模式的一种,浏览器本身也是客户端

  • 无状态:每次请求与响应对双方来说,都是第一次见面,不会因为上一次的请求响应记住彼此

  • 无连接:每次请求建立一个新的连接,响应结束后即断开链接
  • 易扩展:这个主要体现在自定义header和自定义method上

2.2、报文格式

2.2.1、请求报文

  • 报文格式

这里写图片描述

  • sp:空格
  • cr:回车
  • lf:换行
  • 事例报文
GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,mt;q=0.7,zh-TW;q=0.6
Cookie: BAIDUID=8CD26F8282C7E8DAA2B871E466ACD20A:FG=1; BIDUPSID=8CD26F8282C7E8DAA2B871E466ACD20A; PSTM=1493776685; __cfduid=d238880f35642020d2e0ed962a41a29cf1503214889; sugstore=1; pgv_pvi=279248896; BD_HOME=0; H_PS_PSSID=26351_1446_21078_26350_20927; BD_UPN=123253; BD_CK_SAM=1; PSINO=7; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598
  • 第一行是请求行,GET访问、/(根)路径、HTTP 1.0版本
  • 第二行到第十行是Header部分,也就是Host到Cookie都是Header,有冒号分隔的Key Value对
  • 第十一行,也就是最后一行是空白行
  • 没有Body,因为是GET请求

2.2.2、响应报文

  • 报文格式

这里写图片描述

和请求报文的区别在于:响应报文第一行包含响应状态码和消息、Header和Body的内容不同

  • 事例报文
HTTP/1.1 200 OK
Bdpagetype: 1
Bdqid: 0xc35852e10007622b
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html
Cxy_all: baidu+9feddd41845dffd8840a29dc5595cfe4
Date: Thu, 24 May 2018 07:08:36 GMT
Expires: Thu, 24 May 2018 07:08:07 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=26351_1446_21078_26350_20927; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked

<html></html>

2.3、URL

处理URL还经常听说URI,很对人对URL和URI傻傻分不清,这里简单说明一下:

  • URI:Universal Resource Identifier,统一资源标识符
    • 说明:URI用来唯一标识一个资源实例,也就是说只要能确定唯一性,我们就可以将其称之为URL,比如:身份证号
  • URL:Universal Resource Locator,统一资源定位符
    • 说明:URL是通过路径的方式查找和定位资源实例,比如:www.baidu.com/xxxx/index.html,这里表示在www.baidu.com这个域名对于的服务器上的xxxx目录下的index.html文件,index.html文件是唯一确定的,我们通过URL定位到这个文件。

我们常说URL时URI的子集,因为URL是一种通过路径来表示资源的方式。例如:定位邹XX:

  • URI:通过身份证号码
  • URL:湖北省武汉市XXX街XXX号XXX邹XX

2.4、Method

目前HTTP协议定义了如下8中方法:

  • GET:请求获取URL表示的资源,也就是查询服务器资源
  • POST:向服务器提交数据(如:表单或文件),用于更新或创建资源
  • HEAD:向服务器查询Response header
  • PUT:请求服务器存储一个资源,并用URL作为其标识符
  • DELETE:请求服务器删除URL指定的资源
  • TRANCE:请求服务器回显收到的请求,主要用于测试或诊断
  • CONNECT:预留给能够将连接改为管道方式的代理服务器(保留将来使用)
  • OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项和需求

GET和POST是我们最常用的两个方法:

  • GET将查询条件附在URL后面传递到服务器端
  • POST将数据附在Body中发往服务器段

上面描述的内容是协议说明的各个方法的用途,虽然在实际情况下我们几乎不这么用~~~~

2.5、Code

服务器端在收到客户端发来的请求之后需要给出答复(响应),每种相对状态对应一个三位数的状态码,状态码可以分为以下类型:

  • 1xx:告知客户端,服务端受理请求,继续发送余下的数据
  • 2xx:告知客户端,服务器成功接收、处理、响应
  • 3xx:告知客户端,接下来需要重定向,继续下一步请求
  • 4xx:告知客户端,请求报文存在错误,服务端无法理解或处理
  • 5xx:告知客户端,服务端出错,无法正确处理请求

常见状态码:

  • 100 Continue:告知客户端,继续发送请求数据。一般出现在需要上传大文件时,在Head中包含 Expect:100-continue 以征询服务端是否受理请求,如果服务端受理,则响应状态码为100,客户端收到状态码之后POST数据到服务端
  • 200 OK:告知客户端,请求正确处理,响应正常
  • 400 Bad Request:告知客户端,语义有误,当前请求无法被服务器理解
  • 401 Unauthorized:告知客户端,当前请求需要身份认证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。一般出现在服务器需要对客户端进行身份验证的情况下,告知客户端发送凭证信息,如果请求中已经包含凭证,则代表服务端拒绝该凭证
  • 403 Forbidden:告知客户端,请求已接收并理解,但拒绝服务
  • 404 Not Found:告知客户端,请求资源不存在,可能是URL有误
  • 500 Internal Server Error:告知客户端,服务器发生不可预期的错误
  • 503 Server Unavailable:告知客户端,服务端当前处于不可用状态

机器之间对话总是各种Code,Message只是给人看的~,机器之间有时候也会出现语言障碍,并不是所有的服务器和客户端都能理解所有的状态码~

其实100 Continue并不常见~~,1xx似乎都不常见(^_^)

2.6、Header

HTTP 消息头允许客户端和服务器通过 request和 response传递附加信息。一个请求头由不区分大小写的名称后跟一个冒号“:”,冒号后跟具体的值(不带换行符)组成。该值前面的引导空白会被忽略。

根据不同上下文,可将消息头分为:

  • 一般头: 同时适用于请求和响应消息,但与最终消息主体中传输的数据无关的消息头。
  • 请求头: 包含有关要获取的资源或客户端本身更多信息的消息头。
  • 响应头: 包含有关服务器响应的补充信息,如其位置或服务器本身(名称和版本等)的消息头。
  • 实体头: 包含有关实体主体的更多信息,比如主体长(Content-Length)度或其MIME类型。

常见Header如下:

  • Request部分
Header Describe Example
Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html
Accept-Charset 浏览器可以接受的字符编码集 Accept-Charset: iso-8859-5
Accept-Encoding 指定浏览器可以支持的web服务器返回内容压缩编码类型 Accept-Encoding: compress, gzip
Accept-Language 浏览器可接受的语言 Accept-Language: en,zh
Accept-Ranges 可以请求网页实体的一个或者多个子范围字段 Accept-Ranges: bytes
Authorization HTTP授权的授权证书 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control 指定请求和响应遵循的缓存机制 Cache-Control: no-cache
Connection 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) Connection: close
Cookie HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 Cookie: $Version=1; Skin=new;
Content-Length 请求的内容长度 Content-Length: 348
Content-Type 请求的与实体对应的MIME信息 Content-Type: application/x-www-form-urlencoded
Date 请求发送的日期和时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
Expect 请求的特定的服务器行为 Expect: 100-continue
From 发出请求的用户的Email From: [email protected]
Host 指定请求的服务器的域名和端口号 Host: www.zcmhi.com
If-Match 只有请求内容与实体相匹配才有效 If-Match: “737060cd8c284d8af7ad3082f209582d”
If-Modified-Since 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 If-None-Match: “737060cd8c284d8af7ad3082f209582d”
If-Range 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag If-Range: “737060cd8c284d8af7ad3082f209582d”
If-Unmodified-Since 只在实体在指定时间之后未被修改才请求成功 If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards 限制信息通过代理和网关传送的时间 Max-Forwards: 10
Pragma 用来包含实现特定的指令 Pragma: no-cache
Proxy-Authorization 连接到代理的授权证书 Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range 只请求实体的一部分,指定范围 Range: bytes=500-999
Referer 先前网页的地址,当前请求网页紧随其后,即来路 Referer: http://www.zcmhi.com/archives/71.html
TE 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 TE: trailers,deflate;q=0.5
Upgrade 向服务器指定某种传输协议以便服务器进行转换(如果支持) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-Agent User-Agent的内容包含发出请求的用户信息 User-Agent: Mozilla/5.0 (Linux; X11)
Via 通知中间网关或代理服务器地址,通信协议 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 关于消息实体的警告信息 Warn: 199 Miscellaneous warning

- Response部分

Header Describe Example
Accept-Ranges 表明服务器是否支持指定范围请求及哪种类型的分段请求 Accept-Ranges: bytes
Age 从原始服务器到代理缓存形成的估算时间(以秒计,非负) Age: 12
Allow 对某网络资源的有效的请求行为,不允许则返回405 Allow: GET, HEAD
Cache-Control 告诉所有的缓存机制是否可以缓存及哪种类型 Cache-Control: no-cache
Content-Encoding web服务器支持的返回内容压缩编码类型。 Content-Encoding: gzip
Content-Language 响应体的语言 Content-Language: en,zh
Content-Length 响应体的长度 Content-Length: 348
Content-Location 请求资源可替代的备用的另一地址 Content-Location: /index.htm
Content-MD5 返回资源的MD5校验值 Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==
Content-Range 在整个返回体中本部分的字节位置 Content-Range: bytes 21010-47021/47022
Content-Type 返回内容的MIME类型 Content-Type: text/html; charset=utf-8
Date 原始服务器消息发出的时间 Date: Tue, 15 Nov 2010 08:12:31 GMT
ETag 请求变量的实体标签的当前值 ETag: “737060cd8c284d8af7ad3082f209582d”
Expires 响应过期的日期和时间 Expires: Thu, 01 Dec 2010 16:00:00 GMT
Last-Modified 请求资源的最后修改时间 Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT
Location 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 Location: http://www.zcmhi.com/archives/94.html
Pragma 包括实现特定的指令,它可应用到响应链上的任何接收方 Pragma: no-cache
Proxy-Authenticate 它指出认证方案和可应用到代理的该URL上的参数 Proxy-Authenticate: Basic
refresh 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) Refresh: 5; url=http://www.zcmhi.com/archives/94.html
Retry-After 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 Retry-After: 120
Server web服务器软件名称 Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)
Set-Cookie 设置Http Cookie Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1
Trailer 指出头域在分块传输编码的尾部存在 Trailer: Max-Forwards
Transfer-Encoding 文件传输编码 Transfer-Encoding:chunked
Vary 告诉下游代理是使用缓存响应还是从原始服务器请求 Vary: *
Via 告知代理客户端响应是通过哪里发送的 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 警告实体可能存在的问题 Warning: 199 Miscellaneous warning
WWW-Authenticate 表明客户端请求实体应该使用的授权方案 WWW-Authenticate: Basic

更多Header请参考:https://www.iana.org/assignments/message-headers/message-headers.xhtml

3、TCP/IP协议

3.1、协议模型

ISO制定的OSI七层网络模型相信大家都不陌生,它为开放式互连信息系统提供了一种功能结构的框架模型,这个模型把开放系统的通信功能划分为七个层次,从邻接物理媒体的层次开始,分别赋于1,2,……7层的顺序编号,相应地称之为物理层、数据链路层、网络层、运输层、会话层、表示层和应用层。每一层的功能是独立的。它利用其下一层提供的服务并为其上一层提供服务,而与其他层的具体实现无关。

但是这种模型过于庞大、复杂招致了许多批评。与此相对的,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用。

TCP/IP参考模型和OSI参考模型的对比示意图如下:

这里写图片描述

3.2、各层分工

对于TCP/IP协议,每一层所对应的网络协议:

这里写图片描述

这里仅列举其中一部分,并非全部~

TCP/IP四层网络协议没层的作用如下:

  • 应用层:为上层应用软件提供对应协议的网络接口,使应用程序本身摆脱了复杂的网络模块开发。其中,有基于TCP协议的,如文件传输协议(File Transfer Protocol,FTP)、虚拟终端协议(TELNET)、超文本链接协议(Hyper Text Transfer Protocol,HTTP),也有基于UDP协议的。
  • 传输层:为上层提供可靠的端到端(End-to-End)服务,在必要的时候,把数据进行切割,并把数据交个网络层。为保证数据传输的可靠性,传输层协议规定接收端必须发回确认,并且假如分组丢失,必须重新发送
  • 网络层:控制子网的运转,如:逻辑编址、分组传输、路由选择、拥塞控制等
  • 网络接口层:这是TCP/IP软件的最低层,负责接收IP数据报并通过网络发送之,或者从网络上接收物理帧,抽出IP数据报,交给IP层。

3.3、工作流程

TCP/IP是两个不同的协议:TCP协议和IP协议。TCP协议负责应用程序之间的连接:比如客户端浏览器和服务端WEB服务,而IP负责两个计算机之间的通信;

IP协议是无连接的,它不会占用两个正在通信的计算机之间的通信线路。这样,IP 就降低了对网络线路的需求。每条线可以同时满足许多不同的计算机之间的通信需要;

TCP协议是面向连接的,实质是建立在IP协议之上的逻辑连接(类似Cookie和Session的连接方式)。TCP通过接收端回馈确认(ACK)从而为应用层提供面向连接的协议功能;

3.3.1、报文结构

这里写图片描述

如上图所示,TCP报文结构由Header和Data两部分组成,Header的结构稍显复杂,整个Header中,除选项和填充外是固定结构,固定结构大小为20byte(160bit),选项部分不得超过40byte,因此整个Header大小在20~60byte之间:

  • 源端口(source port):客户端应用程序使用的端口,占2byte
  • 目的端口(destination port):服务器应用程序使用的端口,占2byte
  • 序号(sequence number):TCP 是面向字节流的,在一个 TCP 连接中传输的字节流中的每个字节都按照顺序编号,整个字节流被切分成若干个TCP报文,sequence number记录了本段报文内容在整个字节流中的起始位置,需要注意的是,这个32位的序号的起始值是随机产生的,并非从0开始,但是理解的时候,可以假象为0
  • 确认号(acknowledgment number):因为TCP是面向连接的,为了保证可靠性,接收端在收到报文后需要向发送端发送”确认报文”,确认报文中acknowledgment number的值会根据接收报文计算得出:接收报文的sequence number值 + 接收报文中的数据长度。例如:服务端收到的一个data内容1kb的报文,其中sequence number为1024,那么就需要回复一个确认报文,确认报文中的acknowledgment number值为:2048(1024 + 1024),同时2048也是客户端下一次发送的报文的sequence number。这种确认机制保障了TCP的有序性。
  • 数据偏移(offset):首先一个偏移量表示上图中的一行,也就是4byte(32bit)。该值记录着TCP报文中Data的起始位置,也就是Header的长度,占0.5byte(4bit),因此最多能表示15(二进制的4个1)个偏移量,一个偏移量4byte,也因此才有Header的最大长度60byte一说

  • 保留(reserved):保留为今后使用,但目前应置为 0

  • 标志位(tcp flags):六个标志位,个有用处
    • URG(Urgent):表示Data中是否存在紧急数据
    • ACK(Acknowlegemt):表示Acknowledgemt Number是否有效,一般称携带 ACK 标志的 TCP 报文段为确认报文段,TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 设置为 1,也就是边发送接收,边确认
    • PSH(Push):当 PSH = 1 的时候,表示该报文段高优先级,接收方 TCP 应该尽快推送给接收应用程序,而不用等到整个 TCP 缓存都填满了后再交付
    • RST(REST):当 RST = 1 的时候,表示 TCP 连接中出现严重错误,需要释放并重新建立连接,一般称携带 RST 标志的 TCP 报文段为复位报文段
    • SYN(Synchronization):当 SYN = 1 的时候,表明这是一个请求连接报文段,一般称携带 SYN 标志的 TCP 报文段为同步报文段。在 TCP 三次握手中的第一个报文就是同步报文段,在连接建立时用来同步序号。 对方若同意建立连接,则应在响应的报文段中使 SYN = 1 和 ACK = 1
    • FIN(Finish):当 FIN = 1 时,表示此报文段的发送方的数据已经发送完毕,并要求释放 TCP 连接,一般称携带 FIN 的报文段为结束报文段,在 TCP 四次挥手释放连接的时候,就会用到该标志
  • 窗口大小(window size):告知对方,本端目前的TCP缓冲区,下一次报文大小不应该超过该值,避免拥塞
  • 校验和(checksum):由发送端填充,接收端对 TCP 报文段执行 CRC 算法,以检验 TCP 报文段在传输过程中是否损坏,如果损坏这丢弃
  • 紧急指针(urgent pointer):仅在 URG = 1 时才有意义,它指出本报文段中的紧急数据的字节数,当 URG = 1 时该值指示Data中,紧急数据的截止位置。如果存在紧急数据,其实位置一定为0,也就是紧急数据在Data的最前面。
  • 选项(tcp options):可能包含一些其他值,比如:MSS

3.3.2、连接与断开

TCP协议建立连接与断开连接我们称之为:三次握手与四次挥手

这里写图片描述

3.3.2.1、握手
  • 初始状态:客户端处于CLOSE状态,服务端处于LISTEN状态
  • 第一次握手:客户端主动打开连接,发送 TCP 报文,进行第一次握手,然后进入SYN_SEND状态,等待服务器发回确认报文。 这时首部的同步位 SYN = 1,同时初始化一个序号 Sequence Number = J。 TCP 规定,SYN 报文段不能携带数据,但会消耗一个序号
  • 第二次握手:服务器收到了 SYN 报文,如果同意建立连接,则向客户端发送一个确认报文,然后服务器进入SYN_RCVD状态。 这时首部的 SYN = 1,ACK = 1,而确认号 Acknowledgemt Number = J + 1,同时也为自己初始化一个序号 Sequence Number = K。 这个报文同样不携带数据
  • 第三次握手:客户端收到了服务器发过来的确认报文,还要向服务器给出确认,然后进入 ESTABLISHED 状态。 这时首部的 SYN 不再置为 1,而 ACK = 1,确认号 Acknowledgemt Number = K + 1,序号 Sequence Number = J + 1。 第三次握手,一般会携带真正需要传输的数据,当服务器收到该数据报文的时候,就会同样进入 ESTABLISHED 状态。 此时,TCP 连接已经建立

对于建立连接的三次握手,主要目的是初始化序号 Sequence Number,并且通信的双方都需要告知对方自己的初始化序号,所以这个过程也叫 SYN。 这个序号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输问题而乱序,因为TCP 会用这个序号来拼接数据

3.3.2.2、挥手

TCP 有一个特别的概念叫做半关闭,这个概念是说,TCP 的连接是全双工(可以同时发送和接收)的连接,因此在关闭连接的时候,必须关闭传送和接收两个方向上的连接。 客户端给服务器发送一个携带 FIN 的 TCP 结束报文段,然后服务器返回给客户端一个 确认报文段,同时发送一个 结束报文段,当客户端回复一个 确认报文段 之后,连接就结束了。

  • 第一次挥手:客户端向服务器发送结束报文段,然后进入 FIN_WAIT_1 状态。 此报文段 FIN = 1, Sequence Number = M
  • 第二次挥手:服务端收到客户端的结束报文段,然后发送确认报文段,进入 CLOSE_WAIT 状态。 此报文段 ACK = 1, Sequence Number = M + 1。客户端收到该报文,会进入 FIN_WAIT_2 状态
  • 第三次挥手:同时服务端向客户端发送结束报文段,然后进入 LAST_ACK 状态。 此报文段 FIN = 1,Sequence Number = N
  • 第四次挥手:客户端收到服务端的结束报文段,然后发送确认报文段,进入 TIME_WAIT 状态,经过 2MSL 之后,自动进入 CLOSED 状态。 此报文段 ACK = 1, Sequence Number = N + 1。服务端收到该报文之后,进入 CLOSED 状态

关于 TIME_WAIT 过渡到 CLOSED 状态说明
TIME_WAIT 进入 CLOSED 需要经过 2MSL,其中 MSL 就叫做 最长报文段寿命(Maxinum Segment Lifetime),根据 RFC 793 建议该值这是为 2 分钟,也就是说需要经过 4 分钟,才进入 CLOSED 状态。

-

这里的部分内容和图片源自《理解TCP和UDP》,如有侵害到作者的权益,请联系本人[email protected]删除!

4、Cookie与Session

由于HTTP是无连接无状态的网络传输协议,客户端和服务端不会因为之前的通讯而在接下来的交流过程中记住彼此。这在解决实际问题时显得极不方便,不可能每次请求服务时,都在请求报文中包含所有必要的数据。因此,为了解决这个问题,服务端会在第一次成功接收客户端请求时,为这个特定的客户端分配一个储物箱,并将箱子的的编号作为凭证交给客户端,客户端下次请求的时候,带着凭证就能拿出储物箱里的东西,或者往储物箱里存放一些东西下次使用。

Session作为储物箱放在服务端,Cookie作为凭证存储在客户端。客户端每次请求带着Cookie访问自己的Session,以此来实现会话跟踪。

4.1、Cookie

Cookie时服务端颁发给浏览器的身份凭证,浏览器在每次访问服务端的时候,都必须带上当前服务端域名对应的所有Cookie,这一点应由浏览器保证。目前的绝大多数浏览器都支持Cookie,对于不支持Cookie的浏览器,可以将Cookie的值平接在URL中传输。

Cookie是不可以跨域名访问的,比如浏览器同时打开Baidu和Google,Baidu不可以访问Google的Cookie,Google也不能访问Baidu的Cookie,这一点由浏览器保证,在向服务端发送请求时,也不会发生与服务端无关的Cookie。为了安全起见,很多网站的Cookie都是经过加密处理的。

Cookie是有时效性的,默认情况下,浏览器会将Cookie驻留在内存中,浏览器关闭之后Cookie即清除。当设置Cookie的时限为一个大于零的值时,该值即表示Cookie的有效期,浏览器会将Cookie持久化到本地文件系统,即使浏览器关闭也不会清除;当设置Cookie的时限为零时,表示删除该Cookie,Cookie没有删除方法,只能通过设置时限为零来实现;当设置Cookie为一个小于零的值时,即默认情况,Cookie驻留在内存中,并不会持久化,浏览器关闭即清除;

因为浏览器每次发起请求时,都会带上当前域名对应的所有Cookie,所以应尽量保证Cookie短小精悍~

4.2、Session

Session是服务端的会话跟踪技术。服务端在第一次受理客户端的请求时,会为用户开辟一块内存空间,并记录用户状态信息,每个Session空间都对应一个唯一的Session ID作为标识符。然后服务端会将这个Session ID作为Cookie颁发给客户端。这样客户端在接下来每次请求服务端时,都能根据Session ID找到自己的状态信息。

Session时服务端为每个用户开辟的独立内存空间,如果在Session中存放复杂对象时,容易导致内存溢出。应尽量保存Session精简。

Session在创建之后,会在服务端保持一段时间,比如30分钟。在接下来的每一次客户端请求,服务端都会重新刷新Session的存活时间,直到客户端超过30分钟不访问服务端,那么Session就会因为超时而被清除。为了减少不必要的内存占用,客户端可以在确认接下来不再需要保持状态时,主动告知服务端清除Session

5、参考资料

猜你喜欢

转载自blog.csdn.net/chenleiking/article/details/80462727