HTTP协议

来源:互联网 发布:jq 数组删除元素方法 编辑:程序博客网 时间:2024/04/29 22:36

 HTTP请求格式
当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成:
① 请求方法 URI 协议/版本
② 请求头(Request Header)
③ 请求正文
下面是一个HTTP请求的例子:
GET/sample.Jsp HTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=jinqiao&password=1234
(1)请求方法URI协议/版本
请求的第一行是“方法URL协议版本”:GET/sample.jsp HTTP/1.1
以上代码中“GET”代表请求方法,“/sample.jsp”表示URI,“HTTP/1.1代表协议和协议的版本。
根据HTTP标准,HTTP请求可以使用多种请求方法。例如:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet应用中,最常用的方法是GET和POST。
URL完整地指定了要访问的网络资源,通常只要给出相对于服务器的根目录的相对目录即可,因此总是以“/”开头,最后,协议版本声明了通信过程中使用HTTP的版本。
(2)请求头(Request Header)
请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。
Accept:image/gif.image/jpeg.*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.
(3) 请求正文
请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息:
username=jinqiao&password=1234
在以上的例子的HTTP请求中,请求的正文只有一行内容。当然,在实际应用中,HTTP请求正文可以包含更多的内容。

HTTP响应格式

HTTP响应也由三个部分组成,分别是:状态行、消息报头、响应正文。
如下所示,HTTP响应的格式与请求的格式十分类似:
<status-line>
<headers>
<blank line>
[<response-body>]
 正如你所见,在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。
状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
    1xx:指示信息--表示请求已接收,继续处理。
    2xx:成功--表示请求已被成功接收、理解、接受。
    3xx:重定向--要完成请求必须进行更进一步的操作。
    4xx:客户端错误--请求有语法错误或请求无法实现。
    5xx:服务器端错误--服务器未能实现合法的请求。
常见状态代码、状态描述的说明如下。
    200 OK:客户端请求成功。
    400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
    401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
    403 Forbidden:服务器收到请求,但是拒绝提供服务。
    404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
    500 Internal Server Error:服务器发生不可预期的错误。
    503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
下面给出一个HTTP响应报文例子
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>

http请求头:
Accept: text/html,image/*    浏览器通过这个头,告诉服务器它所支持的数据类型
Accept-Charset: 浏览器通过这个头,告诉服务器它采用的字符集
Accept-Encoding:浏览器通过这个头,告诉服务器,它所支持的压缩格式
Accept-Language:浏览器通过这个头,告诉服务器,它所采用的语言
Host:浏览器通过这个头,告诉服务器,我想访问服务器哪台主机
If-Modified-Since:浏览器通过这个头,告诉服务器,它缓存数据时间是多少。
Referer:浏览器通过这个头,告诉服务器,我是从哪个网页点过来的(防盗链)
User-Agent: 浏览器通过这个头,告诉服务器,当前浏览器操作系统的信息,以及浏览器的版本号
Connection:
Date:
http响应头:
Location:这个头通常配合302状态码使用,它用于告诉浏览器你去找谁。
Server:告诉浏览器,服务器的类型
Content-Encoding: 服务器通过这个头,告诉浏览器,回送的数据采用的压缩格式。
Content-Length: 80
Content-Language: zh-cn
Content-Type:这个头用于告诉浏览器,回送数据的类型
Last-Modified:这个头用于告诉浏览器,数据的最后修改时间
Refresh: :这个头用于控制浏览器定时刷新
Content-Disposition: 用于通知浏览器,以下载方式打开回送的数据
Transfer-Encoding: 用于通知浏览器,数据是以分块形式回送的
ETag: 缓存相关的头
Expires: 用于说明网页的失效时间,如果该值为一个<0的值,则服务器是通知浏览器不要缓存
Cache-Control: no-cache  通知浏览器不要缓存
Pragma: no-cache 

allow-range:允许断点续传

range

1、什么是Range?
  当用户在听一首歌的时候,如果听到一半(网络下载了一半),网络断掉了,用户需要继续听的时候,文件服务器不支持断点的话,则用户需要重新下载这个文件。而Range支持的话,客户端应该记录了之前已经读取的文件范围,网络恢复之后,则向服务器发送读取剩余Range的请求,服务端只需要发送客户端请求的那部分内容,而不用整个文件发送回客户端,以此节省网络带宽。
 2、HTTP1.1规范的Range是怎样一个约定呢?
  如果Server支持Range,首先就要告诉客户端,咱支持Range,之后客户端才可能发起带Range的请求。这里套用唐僧的一句话,你不说我怎么知道呢。response.setHeader('Accept-Ranges', 'bytes');
  Server通过请求头中的Range: bytes=0-xxx来判断是否是做Range请求,如果这个值存在而且有效,则只发回请求的那部分文件内容,响应的状态码变成206,表示Partial Content,并设置Content-Range。如果无效,则返回416状态码,表明Request Range Not Satisfiable。如果不包含Range的请求头,则继续通过常规的方式响应。

请求下载整个文件: 

  1. GET /test.rar HTTP/1.1 
  2. Connection: close 
  3. Host: 116.1.219.219 
  4. Range: bytes=0-801 //一般请求下载整个文件是bytes=0- 或不用这个头

一般正常回应

  1. HTTP/1.1 200 OK 
  2. Content-Length: 801      
  3. Content-Type: application/octet-stream 
  4. Content-Range: bytes 0-800/801 //801:文件总大小
安全超文本协议
  安全超文本传输协议(Secure Hypertext Transfer Protocol, S-HTTP)是一种结合HTTP而设计的消息的安全通信协议。S-HTTP协议为HTTP客户机和服务器提供了多种安全机制,这些安全服务选项是适用于Web上各类用户的。还为客户机和服务器提供了对称能力(及时处理请求和恢复,及两者的参数选择)同时维持HTTP的通信模型和实施特征。
  S-HTTP不需要客户方的公用密钥证明,但它支持对称密钥的操作模式。这意味着在没有要求用户个人建立公用密钥的情况下,会自发地发生私人交易。它支持端对端安全传输,客户机可能首先启动安全传输(使用报头的信息),用来支持加密技术。
  在语法上,S-HTTP报文与HTTP相同,由请求行或状态行组成,后面是信头和主体。请求报文的格式由请求行、通用信息头、请求头、实体头、信息主体组成。相应报文由响应行、通用信息头、响应头、实体头、信息主体组成。 
  目前有两种方法来建立连接:HTTPS URI方案和HTTP 1.1请求头(由RFC2817引入)。由于浏览器对后者的几乎没有任何支持,因此HTTPS URI方案仍是建立安全超文本协议连接的主要手段。安全超文本连接协议使用https://代替http://。

问题

请求url中含有%2F是什么?

有的服务器不允许直接使用/, 但是允许用它的ASCII码形式,%2F表示ASCII码0x2F(47)对应的字符, 即/。

chunk

Chunked编码使用若干个Chunk串连而成,由一个标明长度为0chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定下一段正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开

。在最后一个长度为0Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。

例子:

这里面只有一个有意义的chunke以及一个footer。第一个chunk,头部是3134这两个字节,表示的是1和4这两个ascii字符,被http协议解释为十六进制数14,也就是十进制的20。后面紧跟0d0a,再接着是20个字节的chunk正文(图中的011e~0131)。

后面再接着0d0a,然后就是footer了,30表示ascii字符0,http解释为长度是0(也说明了这是最后一个chunk),后面紧跟0d0a,然后正文部分为空,再接0d 0a表示结束。

Last-Modified,Etag,Expire混合

为什么要使用Etag呢?Etag主要为了解决Last-Modified无法解决的一些问题
1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)

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

请求一个文件的流程可能如下:
====第一次请求===
1.客户端发起HTTP GET请求一个文件;
2.服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如"2e681a-6-5d044840")(假设服务器支持Etag生成和已经开启了Etag).状态码200

====第二次请求===
1.客户端发起HTTPGET请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是我们第一次请求时服务器返回的Etag:2e681a-6-5d044840

2.服务器判断发送过来的Etag和计算出来的Etag匹配,因此If-None-Match为False,不返回200,返回304,客户端继续使用本地缓存;

弱ETAG
重新考虑3个问题:
问题1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
解决办法:如果使用强Etag,每次得会要求重新GET页面,如果使用弱Etag,比方说设置成FileEtag Size等,就可以忽略MTime造成的Last-Modified时间修改从而影响了If-Modified-Since(IMS)这个校验了。这点和 弱Etag无关。

问题2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
解决办法:如果是这种情况,Apache会自动判断请求时间和修改时间之间的差值,如果小于1s,Apache 会认为这个文件在这1秒内可 能会再次被修改,因此生成一个弱Etag(Weak Etag),这个Etag仅仅基于MTIME来生成,因此MTIME只能精确到s,所以1s内生成的Etag总是

一样,这样就避免了使用强Etag造成的 1s内频繁的刷新Cache的情况。(貌似不用Etag,仅仅使用Last-Modified就可以解决,但是这针对的仅仅是修改超级频繁的情况,很多文 件可能同时也使用强Etag验证)。弱Etag以W/开始,比如:W/"2e681a"

问题3、某些服务器不能精确的得到文件的最后修改时间;
解决办法:生成Etag,因为Etag可以综合Inode,MTime和Size,可以避免这个问题。


原创粉丝点击