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
- 空格 URL中的空格可以用+号或者编码 %20
- / 分隔目录和子目录 %2F
- ? 分隔实际的 URL 和参数 %3F
- % 指定特殊字符 %25
-
表示书签 %23
- & URL 中指定的参数间的分隔符 %26
- = 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等等。
微信分享/微信扫码阅读