http协议(超文本传输协议),是我们日常应用最常用的应用层协议之一,所有的WWW文件都必须遵守这个标准,是建立在TCP协议(TCP属于传输层协议)之上的一种应用协议。这一节我们通过一下几个点进行阐述:
1、报文构成简要说明
2、请求报文
2.1 请求行
2.1.1 请求行简介
2.1.2 GET和POST的区别
2.2 请求头
2.3 请求体
3、响应报文
3.1 状态行
3.2 响应头
3.3 响应体
希望能通过这几个点对http有个简单的了解。
1、报文构成简要说明
从上图可知,http报文一般有两种:请求报文和响应报文。通过内容的直接划分是如上图所示,我们知道在两种报文中,是具有许多相同的属性的,相同的属性我们都归属于通用头部,这是根据内容所划分的。在实际中,报文主体的前面就叫做http头部,由上面的比较我们知道请求头和响应头是存在相同与相异部分的。
2、 请求报文
请求报文的组成部分有:请求头、报文头、报文体。具体如下例:
2.1 请求行
2.1.1 请求行简介
请求行由请求方法+URL(不包括域名)+http协议与版本组成。我们先说说后两个部分吧:请求的URL与http协议。从图中可知,完整的URL其实是放在请求头中的,请求行的URL只是去除域名的剩余部分。最后简单说一下http协议,http协议其实有两个版本1.0与1.1,前者的请求方法只支持:GET、POST、HEAD,后者在前者的基础上扩充到了8种。再者,http1.1版本又支持了持久连接、以管道方式同时发送多个请求等优化点。
这里我们介绍一下请求方法,总共有8中类型,其中GET和POST是我们最常见而且能满足大部分应用需求的两种:
(1)GET:传递的参数是直接表示在地址栏中,因此不适合作为携带私密或者大量参数的请求所属方式。因为部分浏览器或者服务器对URL长度是具有限制的。
(2)POST:把传递的数据封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,对数据量没有限制,也不会显示在URL中。通常以提交表单的方式来携带请求数据。
(3)HEAD:HEAD跟GET相似,不过服务端接收到HEAD请求时只返回响应头,不发送响应内容。所以,如果只需要查看某个页面的状态时,用HEAD更高效,因为省去了传输页面内容的时间。
(4)Options:返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性。比如,可用该请求用于获取当前URL所支持的方法。若请求成功,会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。
(5)DELETE:删除某一个资源。
(6)PUT:把一个资源存放在指定的位置上。
本质上来讲, PUT和POST极为相似,都是向服务器发送数据,但它们之间有一个重要区别,PUT通常指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器自己决定。
(7)TRACE:回显服务器收到的请求,主要用于测试或诊断。
(8)CONNECT:CONNECT方法是HTTP/1.1协议预留的,能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通信。
2.1.2 GET和POST的区别
作为使用率最高的两种请求方式吗,这里着重说一下GET、POST两种方式的区别:
(a)方法目的:GET是请求服务器数据(读取)、POST是想服务器提交数据。
也因此,可以对GET请求的数据进行缓存(这个缓存可以放在B/C端,也可以放在中间代理节点上,或者Server端上),无副作用。而POST则涉及了改动数据,因此如果对其数据做了缓存,则容易产生问题;
(b)数据携带:GET请求参数直接拼接到URL上,而POST则存放到请求体(body)中。
当然,这只是大家默认的一种规范,在接口上,GET实际上也可以带body,POST也可以在url上携带数据,只是如果没有实际切实的需要,这样打破规范实在是没必要也增加了一些风险;
(c)编码类型:先说结论 GET只支持application/x-www-form-urlencoded,而POST则支持application/x-www-form-urlencoded 或 multipart/form-data,为二进制数据使用多重编码;
application/x-www-form-urlencoded针对简单的key-value场景;multipart/form-data,针对只有文件提交,或者同时有文件和key-value的混合提交表单的场景(也可以这么说:multipart/form-data用以支持向服务器发送二进制数据,以便可以在 POST 请求中实现文件上传等功能)。从数据携带我们可知,通过对URL与body来区分,URL只支持application/x-www-form-urlencoded,body则支持application/x-www-form-urlencoded 、multipart/form-data,为二进制数据使用多重编码。
(d)数据类型支持:URL只支持ASCII字符(虽然空格也是属于ASCII字符,但是不支持),而body则没有什么限制,即使是二进制数据也可以。即在默认情况下,GET只支持ASCII子集,POST则无数据类型限制;
(e)安全性:从数据携带可知,其实数据放在url上是比放在body上有更多机会被泄漏。从数据携带方面可知,在相同的状况与规范下,GET的安全性是比POST低。
但是其实都是不安全的,因为HTTP本身是明文协议。每个HTTP请求和返回的每个byte都会在网络上明文传播,不管是url,header还是body。这里就涉及到数据安全性,要提高数据安全,就要通过端端加密解密——客户端与服务端,目前最普遍的做法就是采用https;
(f)数据长度限制:URL 的最大长度是 2048 个字符,某些数据爬虫也无法处理2000个字节以上的URL。因此在默认情况下,GET携带的数据量会因为URL的限制而受限,但是POST则无限制;
(g)其他:由方法目的中我们可知,GET是允许被缓存请求的,POST则不能,因此GET请求是可以被收藏在书签,参数也能够被保存在浏览历史中,POST则不允许;GET请求一旦后退、刷新可以没什么影响,POST则需要重新提交数据(一般B/C端会重新提醒用户)等。
2.2 请求头部
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。请求头部由关键字/值对组成,每行一对,也是可以根据自己的需求进行补充的。常见的默认请求头(部分)属性有:
User-Agent : 产生请求的浏览器类型;
Accept : 客户端希望接受的数据类型,比如 Accept:text/xml(application/json)表示希望接受到的是xml(json)类型;
Host : 请求的主机名,允许多个域名同处一个IP地址,即虚拟主机;
Content-Length:以8进制表示的请求体的长度(因此默认情况下,POST该属性必须有值);
Content-Type:发送端发送的实体数据的数据类型(如,Content-Type:text/html(application/json)表示发送的是html类型)。content-type属性有:
2.3 请求体
将一个页面表单中的组件值以param1=value1¶m2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。
3、 响应报文
响应报文的组成部分有:状态行、响应头、响应体。具体如下例:
3.1 状态行
状态行也由三部分组成:服务器HTTP协议版本,响应状态码,状态码的文本描述。这个就简单多了,我们常见的状态码有:
3.2 响应头
响应头用于描述服务器的基本信息,以及数据的描述,服务器通过这些数据的描述信息,可以通知客户端如何处理等一会儿它回送的数据。其主要的就是一些服务器的基本信息以及一些Cookie值等,也因此设置HTTP响应头往往和状态码结合起来。
3.3 响应体
响应体为请求需要得到的具体数据,可以为任何类型数据。数据的格式一般通过响应头的Content-Type属性所指定。