HTTP请求具体解释

1. HTTP请求格式      

       做过Socket编程的人都知道,当我们设计一个通信协议时,“消息头/消息体”的切割方式是非经常常使用的。消息头告诉对方这个消息是干什么的,消息体告诉对方怎么干。

HTTP协议传输的消息也是这样规定的。每个HTTP包都分为HTTP头和HTTP体两部分,消息体是可选的,而消息头是必须的。每当我们打开一个网页,在上面点击右键,选择“查看源文件”,这时看到的HTML代码就是HTTP的消息体。那么消息头能够通过浏览器的开发工具或者插件能够看到,假设火狐的Firebug。IE的Httpwatch。

      client通过发送 HTTP 请求向server请求对资源的訪问。 它向server传递了一个数据块。也就是请求信息,HTTP 请求由三部分组成:请求行、  请求头和请求正文。

 请求行:请求方法 URI 协议/版本号

  请求头(Request Header)

 

 请求正文

以下是一个HTTP请求的数据:

POST /index.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: <a target=_blank href="http://localhost/" style="color: rgb(51, 102, 153); text-decoration: none;">http://localhost/</a>
Content-Length:25
Content-Type:application/x-www-form-urlencoded
 
username=aa&password=1234
 

1、请求行:请求方法URI协议/版本号

 请求的第一行是“方法 URL  协议/版本号”,并以 回车换行作为结尾。

请求行以空格分隔。格式例如以下:

POST /index.php HTTP/1.1
以上代码中“GET”代表请求方法,“//ndex.php”表示URI。“HTTP/1.1代表协议和协议的版本号。
        依据HTTP标准,HTTP请求能够使用多种请求方法。

比如:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。

在Internet应用中,最经常使用的方法是GET和POST。

         URL完整地指定了要訪问的网络资源,通常仅仅要给出相对于server的根文件夹的相对文件夹就可以,因此总是以“/”开头,最后,协议版本号声明了通信过程中使用HTTP的版本号。   

请求方法

在 HTTP 协议中,HTTP 请求能够使用多种请求方法。这些方法指明了要以何种方式来訪问 Request-URI 所标识的资源。HTTP1.1 支持的请求方法例如以下表所看到的:

HTTP1.1 中的请求方式:
方法 作用
GET 请求获取由 Request-URI 所标识的资源
POST 请求server接收在请求中封装的实体。并将其作为由 Request-Line 中的 Request-URI 所标识的资源的一部分
HEAD 请求获取由 Request-URI 所标识的资源的响应消息报头
PUT

请求server存储一个资源,并用 Request-URI 作为其标识符

DELETE 请求server删除由 Request-URI 所标识的资源
TRACE 请求server回送到的请求信息,主要用于測试或诊断
CONNECT 保留将来使用
OPTIONS 请求查询server的性能。或者查询与资源相关的选项和需求
 

重点介绍 GET、POST 和 HEAD 三个方法:

(1)GET

        GET 方法用于获取由 Request-URI 所标识的资源的信息,常见的形式是:

        GET Request-URI HTTP/1.1
        GET方法是默认的HTTP请求方法,比如当我们通过在浏览器的地址栏中直接输入网址的方式去訪问网页的时候,浏览器採用的就是 GET 方法向server获取资源。

        我们能够使用GET方法来提交表单数据,用GET方法提交的表单数据仅仅经过了简单的编码,同一时候它将作为URL的一部分向server发送,因此。假设使用GET方法来提交表单数据就存在着安全隐患上。比如:
         Http://localhost/login.php?

username=aa&password=1234

        从上面的URL请求中,非常easy就能够辩认出表单提交的内容。

(?之后的内容)另外由于GET方法提交的数据是作为URL请求的一部分所以提交的数据量不能太大。

这是由于浏览器对url的长度有限制

       各种浏览器也会对url的长度有所限制。以下是几种常见浏览器的url长度限制:(单位:字符)

IE : 2803
Firefox:65536
Chrome:8182
Safari:80000
Opera:190000 

(2)POST

          POST方法是GET方法的一个替代方法。它主要是向Webserver提交表单数据,尤其是大批量的数据。 在请求头信息结束之后的两个回车换行之后(实际是空一行),就是表单提交的数据。如上面提到的post表单数据:

        username=aa&password=1234

        POST方法克服了GET方法的一些缺点。

通过POST方法提交表单数据时,数据不是作为URL请求的一部分而是作为标准数据传送给Webserver。这就克服了GET方法中的信息无法保密和数据量太小的缺点。因此,出于安全的考虑以及对用户隐私的尊重。通常表单提交时採用POST方法。

  从编程的角度来讲,假设用户通过GET方法提交数据,则数据存放在QUERY_STRING环境变量中,而POST方法提交的数据则能够从标准输入流中获取。

 GET与POST方法有下面差别:

      1、  在client,Get方式在通过URL提交数据,数据在URL中能够看到;POST方式。数据放在HTTP包的body中。

      2、 GET方式提交的数据大小有限制(由于浏览器对URL的长度有限制),而POST则没有此限制。

      3、安全性问题。正如在(1)中提到,使用 Get 的时候。參数会显示在地址栏上。而 Post 不会。所以。假设这些数据是中文数据并且是非敏感数据,那么使用 get。假设用户输入的数据不是中文字符并且包括敏感数据。那么还是使用 post为好。

      4.、server取值方式不一样。GET方式取值,如php能够使用$_GET来取得变量的值,而POST方式通过$_POST来获取变量的值。

(3)HEAD

     HEAD 方法与 GET 方法差点儿是同样的,它们的差别在于 HEAD 方法仅仅是请求消息报头,而不是完整的内容。对于 HEAD 请求的回应部分来说,它的 HTTP 头部中包括的信息与通过 GET 请求所得到的信息是同样的。

利用这种方法,不必传输整个资源内容。就能够得到 Request-URI 所标识的资源的信息。这种方法通常被用于測试超链接的有效性。能否够訪问,以及近期是否更新。

    要注意的是。在 HTML 文档中,书写 get 和 post,大写和小写都能够,但在 HTTP 协议中的 GET 和 POST 仅仅能是大写形式。

2. 请求头

每一个头域由一个域名。冒号(:)和域值三部分组成。域名是大写和小写无关的,域值前能够加入不论什么数量的空格符,头域能够被扩展为多行,在每行開始处,使用至少一个空格或制表符。

HTTP最常见的请求头例如以下:

Transport 头域

Connection:

作用:表示是否须要持久连接。

假设server看到这里的值为“Keep-Alive”。或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就能够利用持久连接的长处,当页面包括多个元素时(比如Applet。图片)。显著地降低下载所须要的时间。要实现这一点,server须要在应答中发送一个Content-Length头。最简单的实现方法是:先把内容写入 ByteArrayOutputStream,然后在正式写出内容之前计算它的大小;

比如: Connection: keep-alive   当一个网页打开完毕后,client和server之间用于传输HTTP数据的TCP连接不会关闭。假设client再次訪问这个server上的  网页,会继续使用这一条已经建立的连接

比如:  Connection: close  代表一个Request完毕后,client和server之间用于传输HTTP数据的TCP连接会关闭,  当client再次发送Request,须要又一次建立TCP连接。

Host(发送请求时,该报头域是必需的)

Host请求报头域主要用于指定被请求资源的Internet主机和port号,它通常从HTTP URL中提取出来的。

eg:http://。localhost/index.html
浏览器发送的请求消息中,就会包括Host请求报头域。例如以下:
Host:
localhost

此处使用缺省port号80,若指定了port号8080,则变成:Host:localhost:8080

Client 头域

Accept:

作用:浏览器能够接受的媒体类型(MIME类型),

比如:  Accept: text/html  代表浏览器能够接受server回发的类型为 text/html  也就是我们常说的html文档, 假设server无法返回text/html类型的数据,server应该返回一个406错误(non acceptable)。

通配符 * 代表随意类型。比如  Accept: */*  代表浏览器能够处理全部类型,(一般浏览器发给server都是发这个)

Accept-Encoding:

作用: 浏览器申明自己接收的编码方法。通常指定压缩方法,是否支持压缩。支持什么压缩方法(gzip,deflate),(注意:这不是仅仅字符编码);

比如: Accept-Encoding: gzip, deflate。Server可以向支持gzip/deflate的浏览器返回经gzip或者deflate编码的HTML页面。 很多情形下这可以降低5到10倍的下载时间,也节省带宽。

Accept-Language:

作用: 浏览器申明自己接收的语言。 

语言跟字符集的差别:中文是语言,中文有多种字符集,比方big5,gb2312,gbk等等;

比如: Accept-Language:zh-cn 。假设请求消息中没有设置这个报头域,server假定client对各种语言都能够接受。

User-Agent:

作用:告诉HTTPserver。 client使用的操作系统和浏览器的名称和版本号.

我们上网登陆论坛的时候,往往会看到一些欢迎信息,当中列出了你的操作系统的名称和版本号。你所使用的浏览器的名称和版本号,这往往让非常多人感到非常奇妙,实际上, server应用程序就是从User-Agent这个请求报头域中获取到这些信息User-Agent请求报头域同意client将它的操作系统、浏览器和其他属性告诉server。

比如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)

Accept-Charset:

作用:浏览器申明自己接收的字符集,这就是本文前面介绍的各种字符集和字符编码。如gb2312,utf-8(通常我们说Charset包含了对应的字符编码方案);

比如:Accept-Charset:iso-8859-1,gb2312.假设在请求消息中没有设置这个域,缺省是不论什么字符集都能够接受。

Authorization:授权信息。通常出如今对server发送的WWW-Authenticate头的应答中;

Authorization请求报头域主要用于证明client有权查看某个资源。当浏览器訪问一个页面时,假设收到server的响应代码为401(未授权)。能够发送一个包含Authorization请求报头域的请求,要求server对其进行验证。

Cookie/Login 头域

Cookie:

作用: 最重要的header, 将cookie的值发送给HTTP server

Entity头域

Content-Length

作用:发送给HTTPserver数据的长度。

即请求消息正文的长度。

比如: Content-Length: 38

Content-Type:

作用:

比如:Content-Type: application/x-www-form-urlencoded

Miscellaneous 头域

Referer:

作用: 提供了Request的上下文信息的server,告诉server我是从哪个链接过来的。比方从我主页上链接到一个朋友那里, 他的server就行从HTTP Referer中统计出每天有多少用户点击我主页上的链接訪问    他的站点。

比如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT

Cache 头域

If-Modified-Since:

作用: 把浏览器端缓存页面的最后改动时间发送到server去。server会把这个时间与server上实际文件的最后改动时间进行对照。假设时间一致,那么返回304,client就直接使用本地缓存文件。假设时间不一致。就会返回200和新的文件内容。client接到之后。会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。

比如:If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT。

If-None-Match:

作用: If-None-Match和ETag一起工作。工作原理是在HTTP Response中加入ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。

假设server验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉client使用本地缓存文件。否则将返回200状态和新的资源和Etag.  使用这种机制将提高站点的性能

比如: If-None-Match: "03f2b33c0bfcc1:0"

Pragma:

作用: 防止页面被缓存, 在HTTP/1.1版本号中。它和Cache-Control:no-cache作用一模一样

Pargma仅仅有一个使用方法, 比如: Pragma: no-cache

注意: 在HTTP/1.0版本号中。仅仅实现了Pragema:no-cache, 没有实现Cache-Control

Cache-Control:

作用: 这个是很重要的规则。 这个用来指定Response-Request遵循的缓存机制。各个指令含义例如以下

Cache-Control:Public   能够被不论什么缓存所缓存()

Cache-Control:Private     内容仅仅缓存到私有缓存中

Cache-Control:no-cache  全部内容都不会被缓存

2. HTTP响应格式      

      在接收和解释请求消息后,server会返回一个 HTTP 响应消息。与 HTTP 请求类似,HTTP 响应也是由三个部分组成,各自是:状态行、消息报头和响应正文。

如:

<p>HTTP/1.1 200 OK
Date: Sun, 17 Mar 2013 08:12:54 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8</p><p>
<html>
<head>
<title>HTTP响应演示样例<title>
</head>
<body>
Hello HTTP!
</body>
</html></p><p> </p>

1、状态行

       状态行由协议版本号、数字形式的状态代码,及对应的状态描写叙述组成,各元素之间以空格分隔,结尾时回车换行符,格式例如以下:

HTTP-Version Status-Code Reason-Phrase CRLF

HTTP-Version 表示server HTTP 协议的版本号,Status-Code 表示server发回的响应代码,Reason-Phrase 表示状态代码的文本描写叙述。CRLF 表示回车换行。比如:

HTTP/1.1 200 OK (CRLF)

      状态代码与状态描写叙述

      状态代码由 3 位数字组成, 表示请求是否被理解或被满足。状态描写叙述给出了关于状态码的简短的文字描写叙述。状态码的第一个数字定义了响应类别,后面两位数字没有详细分类。

第一个数字有 5 种取值,例如以下所看到的。

  • 1xx:指示信息——表示请求已经接受,继续处理
  • 2xx:成功——表示请求已经被成功接收、理解、接受。
  • 3xx:重定向——要完毕请求必须进行更进一步的操作
  • 4xx:client错误——请求有语法错误或请求无法实现
  • 5xx:server端错误——server未能实现合法的请求。

常见状态代码、状态描写叙述、说明:
200 OK      //client请求成功
400 Bad Request  //client请求有语法错误,不能被server所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 
403 Forbidden  //server收到请求。可是拒绝提供服务
404 Not Found  //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //server发生不可预期的错误
503 Server Unavailable  //server当前不能处理client的请求,一段时间后可能恢复正常

2、响应正文

响应正文就是server返回的资源的内容,响应头和正文之间也必须用空行分隔

如:

  1. <html>  
  2. <head>  
  3. <title>HTTP响应演示样例<title>  
  4. </head>  
  5. <body>  
  6. Hello HTTP!  
  7. </body>  
  8. </html>  

3 、响应头信息

HTTP最常见的响应头例如以下所看到的:

Cache头域

Date:

作用:生成消息的详细时间和日期,即当前的GMT时间。

比如: Date: Sun, 17 Mar 2013 08:12:54 GMT

Expires:

作用: 浏览器会在指定过期时间内使用本地缓存,指明应该在什么时候觉得文档已经过期,从而不再缓存它。

比如: Expires: Thu, 19 Nov 1981 08:52:00 GMT  

Vary

作用:

比如: Vary: Accept-Encoding

Cookie/Login 头域

P3P

作用: 用于跨域设置Cookie, 这样能够解决iframe跨域訪问cookie的问题

比如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR

Set-Cookie

作用: 很重要的header, 用于把cookie 发送到client浏览器。 每个写入cookie都会生成一个Set-Cookie.

比如: Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/

Entity实体头域:

            实体内容的属性,包含实体信息类型。长度,压缩方法,最后一次改动时间,数据有效性等。

ETag:

作用:  和If-None-Match 配合使用。 (实例请看上节中If-None-Match的实例)

比如: ETag: "03f2b33c0bfcc1:0"

Last-Modified:

作用: 用于指示资源的最后改动日期和时间。(实例请看上节的If-Modified-Since的实例)

比如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT

Content-Type:

作用:WEBserver告诉浏览器自己响应的对象的类型和字符集,

比如:

        Content-Type: text/html; charset=utf-8

  Content-Type:text/html;charset=GB2312

  Content-Type: image/jpeg

Content-Length:

指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的过程中,Content-Length的方式要预先在server中缓存全部数据,然后全部数据再一股脑儿地发给client。

  比如: Content-Length: 19847

Content-Encoding:

作用:文档的编码(Encode)方法。通常是压缩方式。

WEBserver表明自己使用了什么压缩方法(gzip。deflate)压缩响应中的对象。利用gzip压缩文档可以显著地降低HTML文档的下载时间。

比如:Content-Encoding:gzip

Content-Language:

作用: WEBserver告诉浏览器自己响应的对象的语言者

比如: Content-Language:da

Miscellaneous 头域

Server:

作用:指明HTTPserver的软件信息

比如:Apache/2.2.8 (Win32) PHP/5.2.5

X-Powered-By:

作用:表示站点是用什么技术开发的

比如: X-Powered-By: PHP/5.2.5

Transport头域

Connection:

比如: Connection: keep-alive   当一个网页打开完毕后,client和server之间用于传输HTTP数据的TCP连接不会关闭。假设client再次訪问这个server上的网页,会继续使用这一条已经建立的连接

比如:  Connection: close  代表一个Request完毕后。client和server之间用于传输HTTP数据的TCP连接会关闭, 当client再次发送Request,须要又一次建立TCP连接。

Location头域

Location:

作用: 用于重定向一个新的位置, 包括新的URL地址

实例请看304状态实例

HTTP协议是无状态的和Connection: keep-alive的差别

  无状态是指协议对于事务处理没有记忆能力。server不知道client是什么状态。从还有一方面讲。打开一个server上的网页和你之前打开这个server上的网页之间没有不论什么联系。

  HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接。更不能代表HTTP使用的是UDP协议(无连接)。

  从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性。简单地说,当一个网页打开完毕后。client和server之间用于传输HTTP数据的TCP连接不会关闭。假设client再次訪问这个server上的网页。会继续使用这一条已经建立的连接。

  Keep-Alive不会永久保持连接,它有一个保持时间,能够在不同的server软件(如Apache)中设定这个时间。

 

3. 浏览器缓存      

          

       浏览器缓存:包含页面html缓存和图片js,css等资源的缓存。例如以下图,浏览器缓存是基于把页面信息保存到用户本地电脑硬盘里。

        


1、缓存的长处:

     1)server响应更快:由于请求从缓存server(离client更近)而不是源server被对应。这个过程耗时更少,让server看上去响应更快。

     2)降低网络带宽消耗:当副本被重用时会减低client的带宽消耗。客户能够节省带宽费用。控制带宽的需求的增长并更易于管理。

1、缓存工作原理

       页面缓存状态是由http header决定的。一个浏览器请求信息,一个是server响应信息。主要包含Pragma: no-cache、Cache-Control、 Expires、 Last-Modified、If-Modified-Since。当中Pragma: no-cache由HTTP/1.0规定,Cache-Control由HTTP/1.1规定。

       工作原理图:

 

从图中我们能够看到原理主要分三步:

  1. 第一次请求:浏览器通过http的header报头,附带Expires,Cache-Control,Last-Modified/Etag向server请求,此时server记录第一次请求的Last-Modified/Etag                  
  2. 再次请求:当浏览器再次请求的时候,请求头附带Expires。Cache-Control,If-Modified-Since/Etag向server请求
  3. server依据第一次记录的Last-Modified/Etag和再次请求的If-Modified-Since/Etag做对照,推断是否须要更新server通过这两个头推断本地资源未发生变化。客 户端不须要又一次下载。返回304响应。常见流程例如以下图所看到的:



与缓存相关的HTTP扩展消息头

    Expires:设置页面过期时间,格林威治时间GMT

    Cache-Control:更仔细的控制缓存的内容

    Last-Modified:请求对象最后一次的改动时间 用来推断缓存是否过期 通常由文件的时间信息产生 

    ETag:响应中资源的校验值,在server上某个时段是唯一标识的。

ETag是一个能够 与Web资源关联的记号(token)。和Last-Modified功能才不多。也是一个标识符。一般和Last-Modified一起使用,加强server推断的精确度。

    Date:server的时间

    If-Modified-Since:client存取的该资源最后一次改动的时间。用来和server端的Last-Modified做比較

    If-None-Match:client存取的该资源的检验值,同ETag。

Cache-Control的主要參数 
      Cache-Control: private/public Public 响应会被缓存,而且在多用户间共享。 Private 响应仅仅可以作为私有的缓存,不能再用户间共享。


      Cache-Control: no-cache:不进行缓存 
      Cache-Control: max-age=x:缓存时间 以秒为单位 
      Cache-Control: must-revalidate:假设页面是过期的 则去server进行获取。

 

2、关于图片,css,js,flash的缓存

这个主要通过server的配置来实现这个技术,假设使用apacheserver的话。能够使用mod_expires模块来实现:

编译mod_expires模块:

Cd  /root/httpd-2.2.3/modules/metadata

/usr/local/apache/bin/apxs -i -a -c mod_expires.c //编译

编辑httpd.conf配置:加入以下内容

<IfModule mod_expires.c>

ExpiresActive on

ExpiresDefault "access plus 1 month"

ExpiresByType text/html "access plus 1 months"

ExpiresByType text/css "access plus 1 months"

ExpiresByType image/gif "access plus 1 months"

ExpiresByType image/jpeg "access plus 1 months"

ExpiresByType image/jpg "access plus 1 months"

ExpiresByType image/png "access plus 1 months"

EXpiresByType application/x-shockwave-flash "access plus 1 months"

EXpiresByType application/x-javascript      "access plus 1 months"

#ExpiresByType video/x-flv "access plus 1 months"

</IfModule>

解释:第一句--开启服务

第二句--默认时间是一个月

在以下是关于各种类型的资源的缓存时间设置

原文地址:https://www.cnblogs.com/jzssuanfa/p/6953359.html