引子:
(hypertxt transmission protocal)
http最初的出现时为了解决不同人们之间的信息共享的问题。
http是一种基于C/S模型的应用协议,即存在客户端(browser)与服务端(web server)的区别,客户端通过发送不同的请求数据,期望能够从web服务器处获得不同的信息。
而http协议定义的就是一套客户端与web服务器之间交互的约定与规则。
下面说明了3个简单的例子,企图说明http的建议工作原理,如果有发现不合适的地方,请大神们指正,多谢
例子1:
假设我们要自己实现上述的功能,我们应该怎么设计这种cs通信的协议?可以通过一个例子来考虑:女神口渴了,想喝屌丝桌上的可乐,她应该怎么办呢?至少有以下的部分:
1:女神给屌丝说明,她是女神,她想要和可乐
2:屌丝一看女神,顿时魂都没了,立即将可乐全给了女神,只差跪舔(女神就是不一样啊)
在这个栗子中,女神希望得到可乐,所以女神需要说明我的身份,并说明想要的东西(可乐),然后等待对方给可乐即可,屌丝给予其对应的回复。一次HTTP请求最核心的过程与上述类似,客户端说明想要的资源,服务端将资源响应给客户端。对应之前的栗子,在一次http的请求过程中,client需要做的事情有:
1: 对于期望获取对象的一种描述
2:对于自身的描述信息
3:网络传输的可靠性(环境太吵,屌丝听不见怎么办?)
同时作为服务端(屌丝就是天生为女神提供服务的)他做得事情有:
1:是否给女神,如果他是伪娘怎么办?他可能不给女神的面子,直接回绝
2:将可乐给女神,同时也可能给女神他的微信号码
而在现在已经存在的网络协议栈中,TCP能够保证网络的可靠传输,因此只需要考虑第一点和第二点。
所以客户端对获取数据的描述就包括:
客户端可以对服务端返回的信息做出特定的描述,例如在例子中,女神可以要求将可乐放入玻璃杯中,同时必须要加入3个冰块等要求,
获取的方法
获取的文件的路径
Host:
Accept-Encoding:
Accept-Language
客户端对自己的描述就包括:
User-Agent
Referer:
Origin
例子2:关键词,无状态
http本质上是一种无状态的协议,所谓无状态的协议就是对于客户端和web服务器而言,两次http请求之间没有任何状态的关联,即任意的http请求都可以认为是一个独立的事件。
假设女神和屌丝的记忆力都不好,在下一次他们对话的过程中,屌丝就已经不记得女神了,说所以如果每次都要女神解释自己是谁,岂不很麻烦? 为了不怠慢女神,屌丝给了女神一个信物,而屌丝一看到这个信物,就会知道对面是女神,要满足其所有的需求,岂不妙哉,所以在http中就有另外一个需求,如何在无状态的http协议中保持一些状态信息? 这就要谈到cookie
就如上面的栗子所说,所有的cookie都是服务端发送给客户端,保存在客户端的, 在每一次发送的时候,客户端就可以见这些cookie信息发送给服务端,作为前面请求的状态。这里就要谈到,如何使用cookie的问题,包括:
过期时间:
作用的域:(在栗子中就是, 这个信物可以被谁使用,女神可以让任意的人过来去这个可乐么? 还是只能女神自己使用信物?)
作用的路径(在例子中就是, 女神只能在获取可乐的时候使用这个信物,还是女神在获取其他的东西的时候也可以使用这个信物?)
secure, 这个先不管
K-V
例子3:动态服务
似乎女神已经达到了可乐,一切的问题已经完美,但是女神如果想让屌丝给他做一些其它的事情,例如帮忙做作业,女神应该怎么做?
1:女神需要将作业本和书本给屌丝
2:屌丝也不会做啊,怎么办? 屌丝有个好基友学霸,专门解决一切复杂问题,所以雕饰先将女神给的东西都给学霸
3:学霸完成作业,并将作业的结果给屌丝
4:屌丝将结果再给女神
上面这栗子据提到了http的另外一种情况,客户端需要给服务端传递信息啊,要将课本和作业本都给屌丝,就要区分出作业本和课本的区别,而屌丝将结果给女神的时候,也需要区分出作业本,课本和答案之间的区别,在http协议中,就需要使用MIME(multi-purpose Internet Mail extension)进行实现, 就是指明传输给服务端的内容是什么,通过Content-type字段进行描述。
但是学霸不可能将所有的题目一次做完, 所以学霸先让屌丝给一部分的结果给女神, 然后下一部分的内容下一次再给,这个就是chunked
附录:
l 女神:客户端
l 可乐:用户访问的页面中的信息
l 可乐瓶:http响应body
l 作业本等:请求body
l 屌丝:web服务器
l 学霸:动态服务器
l 做作业: post请求
l 喝可乐: Get请求
l 给女神信物的动作:setcookie
l 女神将信物给屌丝:cookie
l 区分作业本与课本: MIME
l 将作业答案分为多次给女神:chunked
http技术说明
通过上面的三个例子,能够最简单说明http的一部分内容,但也仅仅是一部分,甚至是略有不恰当的地方。从下文开始对http的技术进行详细的罗列,方便查看
http请求方法:
1、请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Method Request-URI HTTP-Version CRLF
其中 Method表示请求方法;Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行(除了作为结尾的CRLF外,不允许出现单独的CR或LF字符)。
请求方法(所有方法全为大写)有多种,各个方法的解释如下:
l GET:请求指定的页面信息,并返回实体主体。
l HEAD:只请求页面的首部。
l POST:请求服务器接受所指定的文档作为对所标识的URI的新的从属实体。
l PUT:从客户端向服务器传送的数据取代指定的文档的内容。
l DELETE:请求服务器删除指定的页面。
l OPTIONS:允许客户端查看服务器的性能。
l TRACE:请求服务器在响应中的实体主体部分返回所得到的内容。
l PATCH:实体中包含一个表,表中说明与该URI所表示的原内容的区别。
l MOVE:请求服务器将指定的页面移至另一个网络地址。
l COPY:请求服务器将指定的页面拷贝至另一个网络地址。
l LINK:请求服务器建立链接关系。
l UNLINK:断开链接关系。
l WRAPPED:允许客户端发送经过封装的请求。
l Extension-mothed:在不改动协议的前提下,可增加另外的方法
GET方法:在浏览器的地址栏中输入网址的方式访问网页时,浏览器采用GET方法向服务器获取资源,请求指定的页面信息,并返回实体主体。eg:GET /form.html HTTP/1.1 (CRLF)
POST方法要求被请求服务器接受附在请求后面的数据,常用于提交表单。
HEAD方法与GET方法几乎是一样的,其之请求页面的首部,对于HEAD请求的回应部分来说,它的HTTP头部中包含的信息与通过GET请求所得到的信息是相同的。利用这个方法,不必传输整个资源内容,就可以得到Request-URI所标识的资源的信息。该方法常用于测试超链接的有效性,是否可以访问,以及最近是否更新。
GET与POST方法有以下区别:
(1) 在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。
(2) GET方式提交的数据最多只能有1024字节,而POST则没有此限制。
(3) 安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。
(4) 安全的和幂等的。所谓安全的意味着该操作用于获取信息而非修改信息。幂等的意味着对同一 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。换句话说,GET 请求一般不应产生副作用。从根本上讲,其目标是当用户打开一个链接时,她可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的注解应该通过 POST 请求实现,因为在注解提交之后站点已经不同了(比方说文章下面出现一条注解)。
GET方法的传递参数在url中直接表示出来。
POST方法在报文中的具体存在形式:在html form url encoded里面,