Author 王平安
E-mail pingan8787@qq.com
博 客 www.pingan8787.com
微 信 pingan8787
每日文章 https://0x9.me/KMrv3

HTTP(Hypertext Transfer Protocol)超文本传输协议。是一种详细规定了客户端浏览器和万维网服务器之间相互通讯的规则,通过因特网传送万维网文档的数据传送协议。

一、HTTP的前世今生

超文本传输协议的前身是Xanadu项目,超文本的概念是泰德.纳尔森在1960年提出的。而HTTP在1989年诞生在CERN(欧洲量子物理实验室)。1990年12月,超文本协议在CERN首次上线。1991年夏天,继Telnet等协议之后,超文本传输协议正式成为互联网诸多协议的一份子。

HTTP诞生的原因:为了实现从一台计算机上获取并显示存放在多台计算机里的文件、数据、图片和其他类型的文件而诞生HTTP协议。因为在当时其他诸多已经诞生的协议解决不了这个问题。例如:Telnet、SMTP、POP3、IAMP4、FTP等。所以HTTP协议应运而生。

二、HTTP协议的版本

HTTP 0.9

HTTP 0.9作为HTTP协议的第一个成熟版本。此版本功能非常薄弱。

  • 1.请求只有一行
  • 2.没有HTTP头部信息和错误代码信息
  • 3.只能接收一种类型的数据:纯文本
  • 4.只有一种方法:GET

HTTP 1.0

随着互联网的发展,HTTP 0.9已经不能满足互联网发展的需求。因此HTTP 1.0就这样诞生了。HTTP 1.0的最大改变是引入了POST方法,使得客户端通过HTML表单向服务器发送数据成为可能。从而实现了客户端和服务器端的数据交互。这是WEB应用程序的一个基础。另一个巨大的改变是引入了HTTP头,使得HTTP协议不仅能返回错误代码,并且借助于MIME技术能够传输更为丰富的文件类型,不再局限于纯文本。还可以是图片、动画等其他文件格式。

除此之外,还允许保持连接,即一次TCP连接,可以实现多次通讯。HTTP 1.0默认是传输一次数据后就关闭连接

HTTP 1.1

2000年5月,HTTP 1.1诞生。HTTP 1.1并不像HTTP 1.0HTTP 0.9那样的革命性。但是对HTTP 1.0做了很多功能性的增强。

  • 1.增加了Host头
    使得GET后面只需使用相对路径;
    使得一台主机可以使用多个域名;
  • 2.引入了Range头 使得客户端通过HTTP`下载时只下载内容的一部分,使得多线程下载成为可能;

三、HTTP协议的特点

  • 1.支持C/S模式
    支持基本认证和安全认证。

  • 2.简单快速
    客户端向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GETHEADPOST。每种方法规定了客户端与服务器端联系的不同类型。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通讯速度快。

  • 3.灵活
    HTTP协议允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。

  • 4.HTTP 0.9和HTTP 1.0使用非持续连接
    限制每次连接只处理一个请求,服务器处理完客户端的请求,并收到客户端的应答后,即断开连接。采用这种方式可以节省传输时间。
    HTTP 1.1使用持续连接:不必为每个Web对象创建一个新的连接,一个连接可以传送多个对象。

  • 5.无状态:
    HTTP协议是无状态协议。
    无状态是指协议对于事物处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。

四、HTTP实现原理

在TCP/IP协议栈中的位置
HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。如下图所示:
HTTPS

默认HTTP的端口号为80,HTTPS的端口号为443。

HTTP的请求响应模型
HTTP协议永远都是客户端发起请求,服务器回送响应。如下图所示:
发起请求

这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。

HTTP协议是一个无状态的协议,同一个客户端的这次请求和上次请求是没有对应关系。

工作流程:
一次HTTP操作称为一个事务,其工作过程可分为四步:

  • 1.首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。

  • 2.建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。

  • 3.服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。

  • 4.客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接

如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。

简化版

  • 1.建立连接
  • 2.接收请求
  • 3.处理请求
  • 4.获取资源
  • 5.构建响应
  • 6.回送响应
  • 7.记录日志

五、HTTP的几个重要概念

URI、URL、URN:

  • URI: Uniform Resource Identifier,统一资源标识符;
  • URL: Uniform Resource Locator,统一资源定位符;
  • URN: Uniform Resource Name,统一资源命名符;

其中,URL,URN是URI的子集

Web上地址的基本形式是URI,它代表通用资源标识符。有两种形式:

  • URL:目前URI的最普遍形式就是无处不在的URL或统一资源定位器。
  • URN:URL的一种更新形式,统一资源名称(URN, Uniform Resource Name)不依赖于位置,并且有可能减少失效连接的个数。但是其流行还需假以时日,因为它需要更精密软件的支持。

URI格式

1
scheme://[username:password@]HOST:port/path/to/source

连接(Connection):

一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间

http1.1requestreponse头中都有可能出现一个connection的头,此header的含义是当clientserver通信时对于长链接如何进行处理。

http1.1中,clientserver都是默认对方支持长链接的, 如果client使用http1.1协议,但又不希望使用长链接,则需要在header中指明connection的值为close;如果server方也不想支持长链接,则在response中也需要明确说明connection的值为close。不论request还是responseheader中包含了值为closeconnection,都表明当前正在使用的tcp链接在当天请求处理完毕后会被断掉。以后client再进行新的请求时就必须创建新的tcp链接了。

消息(Message):

HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。

请求(Request):

一个从客户端到服务器的请求信息包括应用于资源的方法资源的标识符协议的版本号

响应(Response):

一个从服务器返回的信息包括HTTP协议的版本号请求的状态(例如“成功”或“没找到”)和文档的MIME类型

资源(Resource):

URI标识的网络数据对象或服务。

实体(Entity):

数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息实体的本身内容

客户机(Client):

一个为发送请求目的而建立连接的应用程序。

用户代理(UserAgent):

初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具。

服务器(Server):

一个接受连接并对请求返回信息的应用程序。

源服务器(OriginServer):

是一个给定资源可以在其上驻留或被创建的服务器。

代理(Proxy):

一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。

代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求。

网关(Gateway):

一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。

网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。

通道(Tunnel):

是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。

缓存(Cache):

反应信息的局域存储。

六、HTTP协议头

HTTP头按照其不同的作用,分为四类:

1.通用头(General Header)

通用头即可以包含在HTTP请求中,也可以包含在HTTP响应中
通用头的作用是描叙HTTP协议本身。比如描叙HTTP是否持续连接Connection头HTTP发送日期Date头描述HTTP所在的TCP连接时间Keep-Alive头,用于缓存控制Cache-Control头等。

2.实体头(Entity Header)

实体头是那些描叙HTTP信息的头。即可出现在HTTP POST方法的请求中,也可以出现在HTTP响应中。
例如Content-TypeContent-length都是描述实体的类型和大小的头都属于实体头。其它还有用于描述实体的Content-Language,Content-MD5,Content-Encoding以及控制实体缓存的ExpiresLast-Modifies头等。

常见的实体头如下:

  • Allow:服务器支持哪些请求方法(如GET、POST等);
  • Content-Encoding:文档的编码(Encode)方法,例如:gzip,见“2.5 响应头”;
  • Content-Language:内容的语言类型,例如:zh-cn;
  • Content-Length:表示内容长度,eg:80,可参考“2.5响应头”;
  • Content-Location:表示客户应当到哪里去提取文档;
  • Content-MD5:MD5 实体的一种MD5摘要,用作校验和。发送方和接受方都计算MD5摘要,接受方将其计算的值与此头标中传递的值进行比较。Eg1:Content-MD5: Eg2:dfdfdfdfdfdfdff==
  • Content-Range:随部分实体一同发送;标明被插入字节的低位与高位字节偏移,也标明此实体的总长度。Eg1:Content-Range: 1001-2000/5000,eg2:bytes 2543-4532/7898
  • Content-Type:标明发送或者接收的实体的MIME类型。Eg:text/html; charset=GB2312主类型/子类型;
  • Expires:为0证明不缓存;
  • Last-Modified:WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间等等。例如:Last-Modified:Tue, 06 May 2008 02:42:43 GMT

3.请求头(HTTP Request Header)

请求头是那些由客户端发往服务器端以便帮助服务器端更好的满足客户端请求的头。
请求头只能出现在HTTP请求中。比如告诉服务器只接收某种响应内容Accept头发送CookiesCookie头显示请求主机域HOST头用于缓存If-Match,If-Match-Since,If-None-Match头用于只取HTTP响应信息中部分信息Range头用于附属HTML相关请求引用Referee头等。

常见请求头如下:

  • Accept:浏览器可接受的MIME类型;
  • Accept-Charset:浏览器可接受的字符集;
  • Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间;
  • Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到;
  • Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中;
  • Connection:表示是否需要持久连接。如果Servlet看到这里的值为“Keep-Alive” ,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小;
  • Content-Length:表示请求消息正文的长度;
  • Cookie:这是最重要的请求头信息之一;
  • From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它;
  • Host:初始URL中的主机和端口;
  • If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“Not Modified”应答;
  • Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝;
  • Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
  • User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用;
  • UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型。

4.响应头(HTTP Response Header)

HTTP响应头是那些描述HTTP响应本身的头,这里并不包含描述HTTP响应中第三部分也就是HTTP信息的头(这部分由实体头负责)。
比如说定时刷新的Refresh头,当遇到503错误时自动重试的Retry-After头,显示服务器信息的Server头,设置COOKIE的Set-Cookie头,告诉客户端可以部分请求的Accept-Ranges头等。

常见响应头如下:

  • Allow服务器支持哪些请求方法(如GETPOST等);
  • Content-Encoding文档的编码(Encode)方法。
    只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的NetscapeWindows上的IE 4IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept-Encoding“))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面;
  • Content-Length表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入ByteArrayOutputStram,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream())发送内容;
  • Content-Type 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentTyep。 可在web.xml文件中配置扩展名和MIME类型的对应关系;
  • Date当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式 的麻烦;
  • Server服务器软件名称及版本。
  • Age响应给客户端的文档可以缓存多长时间
  • Public
  • Vary
  • Set-Cookie
  • Set-Cookie2
  • Expires指明应该在什么时候认为文档已经过期,从而不再缓存它。
  • Last-Modified文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304Not Modified)状态。Last-Modified也可用setDateHeader方法来设置;
  • Location表示客户应当到哪里去提取文档。
    Location通常不是直接设置的,而是通过HttpServletResponsesendRedirect方法,该方法同时设置状态代码为302
  • Refresh表示浏览器应该在多少时间之后刷新文档,以秒计。
    除了刷新当前文档之外,你还可以通过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。注意Refresh的意义是“N秒之后刷新本页面或访问指定页面”,而不是“每隔N秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV="Refresh" ...>。注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但NetscapeIE都支持它。

七、HTTP请求

HTTP请求由三部分组成,分别是:请求行消息报头请求正文
请求行以一个方法符开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:

1
Method  Request-URI  HTTP-Version CRLF

  • Method 表示请求方法;
  • Request-URI 是一个统一资源标识符,也就是资源路径;
  • HTTP-Version 表示HTTP协议版本;
  • CRLF 表示回车和换行。

请求方法:

  • GET 请求获取Request-URI所标识的资源
  • POST 在Request-URI所标识的资源后附加新的数据,常用于提交表单
  • HEAD 请求获取由Request-URI所标识的资源的响应消息报头
  • PUT 请求服务器存储一个资源,并用Request-URI作为其标识
  • DELETE 请求服务器删除Request-URI所标识的资源
  • TRACE 请求服务器回送收到的请求信息,主要用于测试或诊断
    可以追踪一次请求中间所经过的代理服务器有哪些
  • CONNECT 保留将来使用
  • OPTIONS 请求查询服务器的性能,或者查询与资源相关的选项和需求
    可以用来获取服务器端资源支持的方法

八、HTTP响应

在接收和解释请求消息后,服务器返回一个HTTP响应消息。

HTTP响应也是由三个部分组成,分别是:状态行消息报头响应正文

状态行格式如下

1
HTTP-Version  Status-Code  Reason-Phrase  CRLF

  • HTTP-Version 表示服务器HTTP协议的版本;
  • Status-Code 表示服务器发回的响应状态代码;
  • Reason-Phrase 表示状态代码的文本描述。

状态代码有三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:

  • 1xx:指示信息–表示请求已接收,继续处理
  • 2xx:成功–表示请求已被成功接收、理解、接受
  • 3xx:重定向–信息不完整需要进一步补充
  • 4xx:客户端错误–请求有语法错误或请求无法实现
  • 5xx:服务器端错误–服务器未能实现合法的请求

常见http响应状态码

请求收到,继续处理:

  • 100:客户端必须继续发出请求
  • 101:客户端要求服务器根据请求转换HTTP协议版本

操作成功收到,分析,接受:

  • 200:交易成功
  • 201:提示知道新文件的URL
  • 202:接受和处理、但处理未完成
  • 203:返回信息不确定或不完整
  • 204:请求收到,但返回信息为空
  • 205:服务器完成了请求,用户代理必须复位当前已经浏览过的文件
  • 206:服务器已经完成了部分用户的GET请求

重定向:

  • 300:请求的资源可在多处得到
  • 301:永久重定向,在Location响应首部的值仍为当前URL(隐式重定向)
  • 302:临时重定向,在Location响应首部的值仍为新的URL(显示重定向)
  • 303:建议客户端访问其他URL或访问方式
  • 304:Not Modified 请求的资源没有改变 可以继续使用缓存
  • 305:请求的资源必须从服务器指定的地址得到
  • 306:前一版本HTTP中使用的代码,现行版本中不再使用
  • 307:声明请求的资源临时性删除

客户端错误:

  • 400:错误请求,如语法错误
  • 401:未授权
    HTTP 401.1 - 未授权,登录失败
    HTTP 401.2 - 未授权,服务器配置问题导致登录失败
    HTTP 401.3 - ACL 禁止访问资源
    HTTP 401.4 - 未授权 授权被筛选器拒绝
    HTTP 401.5 - 未授权 ISAPI或CGI授权失败
  • 402:保留有效ChargeTo头响应
  • 403:禁止访问
    HTTP 403.1 - 禁止访问 禁止可执行访问
    HTTP 403.2 - 禁止访问 禁止读访问
    HTTP 403.3 - 禁止访问 禁止写访问
    HTTP 403.4 - 禁止访问 要求SSL
    HTTP 403.5 - 禁止访问 要求SSL 128
    HTTP 403.6 - 禁止访问 IP地址被拒绝
    HTTP 403.7 - 禁止访问 要求客户端证书
    HTTP 403.8 - 禁止访问 禁止站点访问
    HTTP 403.9 - 禁止访问 连接的用户过多
    HTTP 403.10 - 禁止访问 配置无效
    HTTP 403.11 - 禁止访问 密码更改
    HTTP 403.12 - 禁止访问 映射器拒绝访问
    HTTP 403.13 - 禁止访问 客户端证书已被吊销
    HTTP 403.15 - 禁止访问 客户端访问许可过多
    HTTP 403.16 - 禁止访问 客户端证书不可信或者无效
    HTTP 403.17 - 禁止访问 客户端证书已经到期或者尚未生效
  • 404:没有发现文件、查询或URL
  • 405:用户在Request-Line字段定义的方法不允许
  • 406:根据用户发送的Accept拖,请求资源不可访问
  • 407:类似401,用户必须首先在代理服务器上得到授权
  • 408:客户端没有在用户指定的饿时间内完成请求
  • 409:对当前资源状态,请求不能完成
  • 410:服务器上不再有此资源且无进一步的参考地址
  • 411:服务器拒绝用户定义的Content-Length属性请求
  • 412:一个或多个请求头字段在当前请求中错误
  • 413:请求的资源大于服务器允许的大小
  • 414:请求的资源URL长于服务器允许的长度
  • 415:请求资源不支持请求项目格式
  • 416:请求中包含Range请求头字段,在当前请求资源范围内没有range指示值, 请求也不包含If-Range请求头字段
  • 417 服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长

服务器端错误:

  • 500部服务器错误
    HTTP 500.100 - 内部服务器错误
    HTTP 500-11 服务器关闭
    HTTP 500-12 应用程序重新启动
    HTTP 500-13 - 服务器太忙
    HTTP 500-14 - 应用程序无效
    HTTP 500-15 - 不允许请求
  • 501实现
  • 502关错误
  • 503务不可用
  • 504关超时

九、HTTP状态保持

HTTP 协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的,好比一个顾客和一个自动售货机或者一个普通的(非会员制)大卖场之间的关系一样。

然而聪明(或者贪心?)的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求,作为传输载体的HTTP协议也添加了文件上载、 cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。

Cookie和Session都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力。

Session可以用Cookie来实现,也可以用URL回写的机制来实现。用Cookie来实现的Session可以认为是对Cookie更高级的应用。

Cookie和Session区别

  • 1.Cookie将状态保存在客户端,Session将状态保存在服务器端;

  • 2.Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。Cookie最早在RFC2109中实现,后续RFC2965做了增强。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies。Session并没有在HTTP的协议中定义;

  • 3.Session是针对每一个用户的,变量的值保存在服务器上,用一个sessionID来区分是哪个用户session变量,这个值是通过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器;

  • 4.就安全性来说:当你访问一个使用session 的站点,同时在自己机子上建立一个cookie,建议在服务器端的SESSION机制更安全些.因为它不会任意读取客户存储的信息。

Session机制

Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。

当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为 session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个 session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 session id将被在本次响应中返回给客户端保存。

Session的实现方式

使用Cookie来实现:
服务器给每个Session分配一个唯一的JSESSIONID,并通过Cookie发送给客户端。

当客户端发起新的请求的时候,将在Cookie头中携带这个JSESSIONID。这样服务器能够找到这个客户端对应的Session。

流程如下图所示:
session
使用URL回显来实现
URL回写是指服务器在发送给浏览器页面的所有链接中都携带JSESSIONID的参数,这样客户端点击任何一个链接都会把JSESSIONID带会服务器。

如果直接在浏览器输入服务端资源的url来请求该资源,那么Session是匹配不到的。

Tomcat对Session的实现,是一开始同时使用Cookie和URL回写机制,如果发现客户端支持Cookie,就继续使用Cookie,停止使用URL回写。如果发现Cookie被禁用,就一直使用URL回写。jsp开发处理到Session的时候,对页面中的链接记得使用response.encodeURL()。

与Cookie相关的HTTP扩展头

  • 1.Cookie:客户端将服务器设置的Cookie返回到服务器;
  • 2.Set-Cookie:服务器向客户端设置Cookie;
  • 3.Cookie2 (RFC2965)):客户端指示服务器支持Cookie的版本;
  • 4.Set-Cookie2 (RFC2965):服务器向客户端设置Cookie。

Cookie的流程

服务器在响应消息中用Set-Cookie头将Cookie的内容回送给客户端,客户端在新的请求中将相同的内容携带在Cookie头中发送给服务器。从而实现会话的保持。

流程如下图所示:
cookie

十、Web缓存

什么是Web缓存

WEB缓存(cache)位于Web服务器和客户端之间。

缓存会根据请求保存输出内容的副本,例如html页面,图片,文件,当下一个请求来到的时候:如果是相同的URL,缓存直接使用副本响应访问请求,而不是向源服务器再次发送请求。

HTTP协议定义了相关的消息头来使WEB缓存尽可能好的工作。

Web缓存的优点

    1. 减少相应延迟:因为请求从缓存服务器(离客户端更近)而不是源服务器被相应,这个过程耗时更少,让web服务器看上去相应更快。
    1. 减少网络带宽消耗:当副本被重用时会减低客户端的带宽消耗;客户可以节省带宽费用,控制带宽的需求的增长并更易于管理。

与缓存相关的HTTP消息头

  • Expires:指示响应内容过期的时间,格林威治时间GMT
  • Cache-Control:更细致的控制缓存的内容
  • Last-Modified:响应中资源最后一次修改的时间
  • ETag:响应中资源的校验值,在服务器上某个时段是唯一标识的。
  • Date:服务器的时间
  • If-Modified-Since:客户端存取的该资源最后一次修改的时间,同Last-Modified。
  • If-None-Match:客户端存取的该资源的检验值,同ETag。

客户端缓存生效的常见流程

服务器收到请求时,会在200 OK中回送该资源的Last-Modified和ETag头,客户端将该资源保存在cache中,并记录这两个属性。当客户端需要发送相同的请求时,会在请求中携带If-Modified-Since和If-None-Match两个头。两个头的值分别是响应中Last-Modified和ETag头的值。服务器通过这两个头判断本地资源未发生变化,客户端不需要重新下载,返回304响应。

常见流程如下图所示:
缓存

Web缓存机制

HTTP/1.1中缓存的目的是为了在很多情况下减少发送请求,同时在许多情况下可以不需要发送完整响应。前者减少了网络回路的数量;HTTP利用一个“过期(expiration)”机制来为此目的。后者减少了网络应用的带宽;HTTP用“验证(validation)”机制来为此目的。

HTTP定义了3种缓存机制

  • 1.Freshness:允许一个回应消息可以在源服务器不被重新检查,并且可以由服务器和客户端来控制。例如,Expires回应头给了一个文档不可用的时间。Cache-Control中的max-age标识指明了缓存的最长时间;
  • 2.Validation:用来检查以一个缓存的回应是否仍然可用。例如,如果一个回应有一个Last-Modified回应头,缓存能够使用If-Modified-Since来判断是否已改变,以便判断根据情况发送请求;
  • 3.Invalidation: 在另一个请求通过缓存的时候,常常有一个副作用。例如,如果一个URL关联到一个缓存回应,但是其后跟着POST、PUT和DELETE的请求的话,缓存就会过期。

十一、HTTP代理服务器

代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息。形象的说:它是网络信息的中转站。

代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取回网页而是向代理服务器发出请求,Request信号会先送到代理服务器,由代理服务器来取回浏览器所需要的信息并传送给你的浏览器。

而且,大部分代理服务器都具有缓冲的功能,就好象一个大的Cache,它有很大的存储空间,它不断将新取得数据储存到它本机的存储器上,如果浏览器所请求的数据在它本机的存储器上已经存在而且是最新的,那么它就不重新从Web服务器取数据,而直接将存储器上的数据传送给用户的浏览器,这样就能显著提高浏览速度和效率。

更重要的是:Proxy Server(代理服务器)是Internet链路级网关所提供的一种重要的安全功能,它的工作主要在开放系统互联(OSI)模型的对话层。

HTTP代理服务器的主要功能

  • 1.突破自身IP访问限制,访问国外站点。如:教育网、169网等网络用户可以通过代理访问国外网站;

  • 2.访问一些单位或团体内部资源,如某大学FTP(前提是该代理地址在该资源的允许访问范围之内),使用教育网内地址段免费代理服务器,就可以用于对教育 网开放的各类FTP下载上传,以及各类资料查询共享等服务;

  • 3.突破中国电信的IP封锁:中国电信用户有很多网站是被限制访问的,这种限制是人为的,不同Serve对地址的封锁是不同的。所以不能访问时可以换一个国 外的代理服务器试试;

  • 4.提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时, 则直接由缓冲区中取出信息,传给用户,以提高访问速度;

  • 5.隐藏真实IP:上网者也可以通过这种方法隐藏自己的IP,免受攻击。

HTTP代理图示:
代理
对于客户端浏览器而言,http代理服务器相当于服务器。
而对于Web服务器而言,http代理服务器又担当了客户端的角色。

十二、虚拟主机的实现

什么是虚拟主机

虚拟主机:是在网络服务器上划分出一定的磁盘空间供用户放置站点、应用组件等,提供必要的站点功能与数据存放、传输功能。

所谓虚拟主机,也叫“网站空间”就是把一台运行在互联网上的服务器划分成多个“虚拟”的服务器,每一个虚拟主机都具有独立的域名和完整的Internet服务器(支持WWW、FTP、E-mail等)功能。一台服务器上的不同虚拟主机是各自独立的,并由用户自行管理。但一台服务器主机只能够支持一定数量的虚拟主机,当超过这个数量时,用户将会感到性能急剧下降。

虚拟主机的实现原理

虚拟主机是用同一个WEB服务器,为不同域名网站提供服务的技术。Apache、Tomcat等均可通过配置实现这个功能。
相关的HTTP消息头:Host。
例如:Host: www.baidu.com
客户端发送HTTP请求的时候,会携带Host头,Host头记录的是客户端输入的域名。这样服务器可以根据Host头确认客户要访问的是哪一个域名。

节选自 Apache之HTTP协议