HTTP消息

现在所用的多数是HTTP/1.1,相对于HTTP/1.0,1.1充分考虑了分层代理、缓存、永久连接以及虚拟主机等方面。

我主要参考了《HTTP权威指南》以及RFC2616。

URL

URI是统一资源标识符,URL是URL的比较常见的表现方式,叫统一资源定位符。定位意味着提供了资源的具体地址,是绝对的路径。URI还有其他的表现形式,比如URN,统一资源名称。

长度要求:

HTTP协议本身没有对URI的长度作出限制,但服务器端应该尽量避免URL长度超过255字节,因为有些老的客户端可能不能正确支持这种长度。

格式要求:

方案://HOST:端口/路径。方案指的就是使用什么协议,有http,ftp,telnet,file,mailto,https等等。
http的URL格式一般都是http://主机名:端口号/绝对路径。端口号是空的话,那就默认是80。URI对协议以及主机名是不区分大小写的,但后面的绝对路径却不确定,有的平台区分,有的平台不区分。一般资源都是映射到磁盘路径上的,那么,Windows是不区分大小写的;Unix/Linux是区分大小写的。

其实URL格式后面还有查询,片段等组件。查询字符串很常见,比如我们要根据某些参数利用get方法获取数据库中的数据,会在后面带参数,如: http://dailyblog.applinzi.com/?keyword=python

在URL中有一些是不能传递的,都要进行编码。

编码的格式为:%加字符的ASCII码,即一个百分号%,后面跟对应字符的ASCII(16进制)码值。例如 空格的编码值是"%20"。 下表中列出了一些URL特殊符号及编码

    • URL 中+号表示空格 %2B
  1. 空格 URL中的空格可以用+号或者编码 %20
  2. / 分隔目录和子目录 %2F
  3. ? 分隔实际的 URL 和参数 %3F
  4. % 指定特殊字符 %25
  5. 表示书签 %23

  6. & URL 中指定的参数间的分隔符 %26
  7. = URL 中指定参数的值 %3D

报文

HTTP消息包括请求和响应消息两种,格式都是起始行(start-line,0个或者多个头部域,空行或者数据。

例子:

    请求消息:
        GET /category/django HTTP/1.1
        HOST: dailyblog.applinzi.com
        Accept:text/html.application/xml....
        ......
    响应消息:
        HTTP/1.1 200 OK
        Server:sae
        Date: Thu,25 May 2017 05:34:13 GMT
        Content-type:text/html charset=utf-8
        Content-Length:7842
        Connection:keep-alive
        ......

数据不是必选的,有时候没有,比如有些请求报文。

一、起始行

起始行同样分为请求行和响应行。

1、请求行

请求行由方法,URI,HTTP版本组成。

例子:GET /dailyblog/ HTTP/1.1

HTTP常用的方法就是GET、POST、PUT、HEAD、DELETE、OPTIONS、TRACE等。

最最常用的当然就是GET和POST的了。 关于GET和POST,网上有很多的介绍。

可能大家都在传GET和POST的区别是:

GET使用URL或Cookie传参。而POST将数据放在BODY中。
GET的URL会有长度上的限制,则POST的数据则可以非常大。
POST比GET安全,因为数据在地址栏上不可见。

但其实这种说法是不对的,至少说是不严谨的。实际上,GET和POST的区别仅限于在HTTP协议中的规范:即GET用于从服务器中获取资源,POST用于向服务器输入数据。

没人规定一定GET方法就一定要在URL中传递参数,也可以写在Body中,也同样没人规定POST方法传递数据就一定要写在body中。也就是说,GET比POST安全是没有意义的。

HEAD方法是只获取资源的首部信息,它主要用于测试超链接的有效性,可用性和最近的修改。

例子:

请求:HEAD dailyblog/ HTTP/1.1

 响应:HTTP/1.1 200 OK

PUT方法用于在服务器创建资源或者更新资源。乍一看,它和POST是相同的,但它和POST是有本质区别的。

PUT是幂等的,DELETE也是幂等的,比如我用PUT或者DELETE修改一个资源,不管操作多少次,每次操作后的结果并没有什么不同 POST操作既不是安全的,也不是幂等的,如果常见的POST重复加载的问题,我们进行了多少次POST的操作,最后就创建了多少个资源,这也是为什么Chrom等浏览器,在刷新POST请求时会有弹窗提示。

这么说应该知道什么场景用PUT,什么场景用post了吧。比如我们扫一个二维码,扫这一次都从账户里减100元,每次扫都减,那么就用POST。如果我们更新一个用户信息,假如说每次传递的数据一致,结果也相同,那么我就用PUT。

DELETE方法用来删除服务器的资源。假如响应包括实体,如果成功,响应应该返回200。假如响应不包括实体且成功实施,则返回204。如果动作没有实施则返回202.

2.响应行

响应行是服务器所做的响应。

HTTP/1.1 200 OK

那看到这就要学习一下状态码了。其实状态码有很多,我不可能吧所有的一下子都记住,只能从大类中分。

1、1xx

主要包括100和101,是临时响应,只应用在HTTP/1.1中,服务器不能向HTTP/1.0发送该状态码。

2、2xx

该类状态码表示被服务器成功接收,理解和接受了。有200 ok;201 Created等等。当然最最常用的就是200了。它请求已经成功,该响应返回的信息取决于请求中使用的方法。

3、3xx

重定向状态码,这种状态码指示用户代理需要采取更进一步的行为来完成请求。当且仅当第二次的请求所使用的方法是GET或HEAD时,所需要行为才可能被用户代理在不通知用户的情况下提交。

上图中Location指定了要重定向的目的地址。

关于3xx的状态码请看下面提供的具体状态码链接,那里说的比较详细。我把HTTP权威指南中的一段话copy过来:

从上面看到,服务器选择怎样的状态码取决于客户端的HTTP的版本。

4、4xx

4xx状态码表示客户端有错误。该类状态码真的是用得很多的,至少在我写Django博客的时候用的挺多。

400 请求错误,该请求服务器无法理解。
401 验证错误。服务器可能需要验证信息,比如需要登录,你未登录。
403 权限错误。服务器可能对URI设置了权限,一些用户无法访问。
404 Bingo,它粗来了。大声地读:Not Found。

5、5xx

表示服务器出现错误。最常见的就是500了,服务器内部发生错误。其他的还见下面的链接吧。

具体的状态码含义请见:http://tool.oschina.net/commons?type=5

二、头部域

头部域包括通用头部,请求头部域以及相应头部域等等。

通用头部比如说Date,Connection,Cache-Control等等;

请求头部就只是在请求报文中出现的。 Host,Referer,Accept等等。Accept包括Accept-Language,Accept-Encoding等等。其实请求头部还是蛮多的,比如条件请求头部,即带if的;还有Cookie等安全请求头部。

相应头部域,包括Server啊,Set-Cookie,Location,Content-type,Expires等等。

--------EOF---------
微信分享/微信扫码阅读