HTTP 详解(上)---请求报文、响应报文、状态码、缓存机制

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
主要特点


  • •简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
  • 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
  • 支持B/S及C/S模式。

http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
从上面的URL可以看出,一个完整的URL包括以下几部分:
  • 协议部分:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在”HTTP”后面的“//”为分隔符
  • 域名部分:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用
  • 端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口
  • 虚拟目录部分:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”
  • 文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
  • 锚部分:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分
  • 参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
  • 1. Request

    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:
    请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
    HTTP 详解(上)---请求报文、响应报文、状态码、缓存机制
    1.1. 请求行 由 3 部分组成,分别为:请求方法、URL(不包含域名) 以及协议版本,之间由空格分隔;
    请求方法包括 GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE 以及扩展 方法,当然并不是所有的服务器都实现了所有的方法,部分方法即便支持,出 于安全性的考虑也是不可用的;

    协议版本的格式为:HTTP/主版本号.次版本号,常用的有 HTTP/1.0 和 HTTP/1.1。

    1.2. 请求头部:请求头部为请求报文添加了一些附加信息,由“名/值”对组成,每行一对, 名和值之间使用冒号分隔。(请求的服务器地址,指定连接的属性 keep-alive ,可接受编码格式,可接受数据压缩格式,可接受的语言等)

    1.3. 空行 请求头的最后会有一个空行,表示请求头部结束,接下来为请求正文,这 一行非常重要,必不可少。

    1.4. 请求正文 可选部分,比如 GET 请求就没有请求正文
    HTTP 详解(上)---请求报文、响应报文、状态码、缓存机制
    HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
    HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

    2. Response

    一般情况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。主要由状态行、响应头、空行、响应正文 4 部分组成。
    HTTP 详解(上)---请求报文、响应报文、状态码、缓存机制
    2.1. 状态行 由 3 部分组成,分别为:协议版本,状态码,状态码描述,之间由空格分隔;
    2.2. 响应头 与请求头类似,为响应报文添加了一些附加信息。 (响应正文的类型,长度,编码,压缩格式,语言等)
    HTTP 详解(上)---请求报文、响应报文、状态码、缓存机制

    3.常见 HTTP 首部字段。

    a、通用首部字段(请求报文与响应报文都会使用的首部字段)
    Date:创建报文时间
    Connection:连接的管理
    Cache-Control:缓存的控制
    Transfer-Encoding:报文主体的传输编码方式,如 Transfer-Encoding:chunked。

    b、请求首部字段(请求报文会使用的首部字段)
    Host:请求资源所在服务器
    Accept:可处理的媒体类型
    Accept-Charset:可接收的字符集
    Accept-Encoding:可接受的内容编码
    Accept-Language:可接受的自然语言
    Referer:HTTP Referer 是 header 的一部分,当浏览器向 web 服务器发送请求的时候, 一般会带上 Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信 息用于处理。比如从我主页上链接到一个朋友那里,他的服务器就能够从 HTTP Referer 中统计出每天有多少用户点击我主页上的链接访问他的网站。如果是 CSRF 攻击传来的请 求,Referer 字段会是包含恶意网址的地址,这时候服务器就能识别出恶意的访问。

    c、响应首部字段(响应报文会使用的首部字段)
    Accept-Ranges:可接受的字节范围
    Location:令客户端重新定向到的
    URI Server:HTTP 服务器的安装信息

    d、实体首部字段(描述请求报文与响应报文的的实体部分使用的首部字段)
    Allow:资源可支持的 HTTP 方法
    Content-Type:实体主类的类型 text/html
    Content-Encoding:实体主体适用的编码方式

    4. http 的浏览器缓存机制

    4.1. Last-Modified 和 If-Modified-Since

    Last-Modified 与 If-Modified-Since 都是用于记录页面最后修改时间的 HTTP 头 信 息 , 只 是 Last-Modified 是 由 服 务 器 往 客 户 端 发 送 的 HTTP 头(标记此文件在服务期端最后被修改的时间) , 而 If-Modified-Since 则是由客户端往服务器发送的头,可以看到,再次请求本地存在的缓存 页面时,客户端会通过 If-Modified-Since 头把浏览器端缓存页面的最后一次被服务器修改 的时间一起发到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行 比较,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,就返回 HTTP 状态码 200 和新的文件内容,客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显 示到浏览器中;如果是最新的,则返回 304 告诉客户端其本地缓存的页面是最新的,就直 接把本地缓存文件显示到浏览器中,这样在网络上传输的数据量就会大大减少,同时也减轻了服务器的负担。

    4.2. ETag 和 If-None-Match

    ETag 和 If-None-Match 是一种常用的判断资源是否改变的方法。类似于 Last-Modified 和 If-Modified-Since。但是有所不同的是 Last-Modified 和 If-Modified-Since 只判断资源的 最后修改时间,而 ETag 和 If-None-Match 可以是资源任何的任何属性,比如资源的 MD5 等。

    ETag 和 If-None-Match 的工作原理是在 HTTPResponse 中添加 ETags 信息(服务器会为每个资源分配对应的 ETag 值,根据资源的内容得到其值。当资源内容发 生改变时,其值也会改变)。当客户 端再次请求该资源时,将在 HTTPRequest 中加入 If-None-Match 信息(也就是 ETags 的 值)。如果服务器验证资源的 ETags 没有改变(该资源的内容没有改变),将返回一个 304 状态;否则,服务器将返回 200 状态,并返回该资源和新的 ETags

    4.3. 既然有了 Last-Modified,为什么还要用 ETag 字段呢?

    1.某些文件修改非常频繁,比如在秒以下的时间内进行修改(比方说 1s 内修改了 N 次),If-Modified-Since 能检查到的粒度是秒级的,这种修改无法体现

    2.一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这 个时候我们并不希望客户端认为这个文件被修改了,而重新 GET.

    3.某些服务器不能精确的得到文件的最后修改时间

    4.4 .Expires / Cache-Control

    用来控制缓存的失效日期,控制浏览器是直接从浏览器缓存取数据还是重新发请求到
    服务器取数据。
    Expires 是 Web 服务器响应消息头字段,在响应 http 请求时告诉浏览器在过期时间前 浏览器可以直接从浏览器缓存取数据,而无需再次请求。Expires 的一个缺点就是,返回 的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相 差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在 HTTP1.1 版开始,使 用 Cache-Control: max-age=(秒)替代

    Cache-Control,比如: Cache-Control: max-age=315360000 这里声明的是一个相对的秒数,表示从现在起,315360000 秒内缓存都是有效的,这 样就避免了服务端和客户端时间不一致的问题。 但是 Cache-Control 是 HTTP1.1 才有的,不适用于 HTTP1.0,而 Expires 既适用于 HTTP1.0,也适用于 HTTP1.1,所以说在大多数情况下同时发送这两个头会是一个更好的 选择,当客户端两种头都能解析的时候,会优先使用 Cache-Control

    5.HTTP之状态码

    状态代码有三位数字组成,第一个数字定义了响应的类别,共分五种类别:

    1xx:指示信息–表示请求已接收,继续处理


    2xx:成功–表示请求已被成功接收、理解、接受
    200 OK 服务器已成功处理了请求并提供了请求的网页。
    202 Accepted 已经接受请求,但处理尚未完成
    204 No Content 没有新文档,浏览器应该继续显示原来的文档。
    206 PartialContent 客户端进行了范围请求。响应报文中由 Content-Range 指定实体 内容的范围。实现断点续传


    3xx:重定向–要完成请求必须进行更进一步的操作
    301 Moved Permanently 永久性重定向。请求的网页已永久移动到新位置。
    302(或 307) Moved Temporatily 临时性重定向。请求的网页临时移动到新位置。
    304 Not Modified 未修改。自从上次请求后,请求的内容未修改过


    4xx:客户端错误–请求有语法错误或请求无法实现
    401 Unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含一个 WWW-Authenticate 头,浏览器据此显示用户名字/密码对话框,然后在填写合适的 Authorization 头后再次发出请求。
    403 Forbidden 服务器拒绝请求。———-403.6- IP address rejected
    404 Not Found 服务器上不存在客户机所请求的资源


    5xx:服务器端错误–服务器未能实现合法的请求