HTTP协议学习笔记(一)
1.HTTP协议用于客户端和服务端之间的通信
客户端:请求访问文本或图像等资源的一端
服务端:提供资源响应的一端
在两台计算机之间使用HTTP协议通信时,在一条通信线路上必定是客户端,另一端则是服务端
在实际情况下,客户端和服务端的角色有可能互换,仅从一条通信线路来说,服务端和客户端的角色是确定的
HTTP协议能够区分谁是客户端,谁是服务端
2.通过请求和响应的交换达成通信
HTTP协议规定,请求从客户端发出,最后服务端响应该请求并返回
肯定先从客户端开始建立通信,服务端再响应请求
下面是一个示例
客户端(发送请求):
GET / HTTP/1.1
Host:hacke.jp
服务端(发送响应):
HTTP/1.1 200 OK
Data:Tue, 10 Jul 2012 06:50:15 GMT
Content-Length:362
Content-Type:text/html
<html>
...
3.HTTP是不保存状态的协议
HTTP是一种不保存状态,即无状态协议
HTTP协议自身不对请求和响应之间的通信状态进行保存。协议对于发送过的请求和响应都不做持久化处理。
使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求和响应报文的信息。
这是为了更快的处理大量事务,确保协议的可延伸性。
HTTP/1.1虽然是一种无状态协议,为了实现保持状态的功能,引入了cookie技术,来管理状态。
4.请求URI定位资源
HTTP协议使用URI定位互联网上的资源。正是因为URI的特定功能,能在互联网上任意位置的资源都能访问到。
URI和URL有什么区别:URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。而URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。而URN,uniform resource name,统一资源命名,是通过名字来标识资源,比如mailto:java-net@java.sun.com。也就是说,URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。
统一资源标志符URI就是在某一规则下能把一个资源独一无二地标识出来。拿人做例子,假设这个世界上所有人的名字都不能重复,那么名字就是URI的一个实例,通过名字这个字符串就可以标识出唯一的一个人。现实当中名字当然是会重复的,所以身份证号才是URI,通过身份证号能让我们能且仅能确定一个人。那统一资源定位符URL是什么呢。也拿人做例子然后跟HTTP的URL做类比,就可以有:动物住址协议://地球/中国/浙江省/杭州市/西湖区/某大学/14号宿舍楼/525号寝/张三.人可以看到,这个字符串同样标识出了唯一的一个人,起到了URI的作用,所以URL是URI的子集。URL是以描述人的位置来唯一确定一个人的。在上文我们用身份证号也可以唯一确定一个人。对于这个在杭州的张三,我们也可以用:身份证号:123456789来标识他。所以不论是用定位的方式还是用编号的方式,我们都可以唯一确定一个人,都是URl的一种实现,而URL就是用定位的方式实现的URI
回到Web上,假设所有的Html文档都有唯一的编号,记作html:xxxxx,xxxxx是一串数字,即Html文档的身份证号码,这个能唯一标识一个Html文档,那么这个号码就是一个URI。而URL则通过描述是哪个主机上哪个路径上的文件来唯一确定一个资源,也就是定位的方式来实现的URI。对于现在网址我更倾向于叫它URL,毕竟它提供了资源的位置信息,如果有一天网址通过号码来标识变成了http://741236985.html,那感觉叫成URI更为合适,不过这样子的话还得想办法找到这个资源
当客户端请求访问资源而发送请求时,URI需要将作为请求报文中的请求URI包含在内。指定请求URI的方式有很多。
下面两种:
5.告知服务器意图HTTP方法
GET:获取资源
GET方法用来请求访问已被URI识别的资源。指定的资源经服务器端解析后返回响应内容。如果请求的资源为文本,那就保持原样返回。
最常用于向服务器查询某些信息。必要时,可以将查询字符串参数追加到URL末尾,以便将信息发送给服务器。
HEAD:获取报文首部
HEAD和GET本质是一样的,区别在于HEAD不含有呈现数据,而仅仅是HTTP头信息,就是不返回报文主体。有的人可能觉得这个方法没什么用,其实不是这样的。想象一个业务情景:欲判断某个资源是否存在,我们通常使用GET,但这里用HEAD则意义更加明确。
POST:传输实体文本
虽然用GET方法也可以传输实体的主体。但一般不用GET方法进行传输,而是用POST方法。虽说POST的功能与GET很相似,但POST的主要目的并不是获取响应的主体内容
PUT:传输文件
PUT方法用来传输文件。就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。但是HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全问题,故一般不用。
DELETE:删除文件
指明客户端想让服务器删除某个资源,与PUT方法相反,按URI删除指定资源
OPTIONS:询问支持的方法
OPTIONS方法用来查询针对请求URI指定资源支持的方法(客户端询问服务器可以提交哪些请求方法)
TRACE:追踪路径
客户端可以对请求消息的传输路径进行追踪,TRACE方法是让Web服务器端将之前的请求通信还给客户端的方法
CONNECT:要求用隧道协议连接代理
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(安全套接层)和TLS(传输层安全)协议把通信内容加密后经网络隧道传输。
6.HTTP/1.0、HTTP/1.1支持的方法
7.持久连接节省通信量
HTTP协议初始版本中,每进行一次HTTP通信一次HTTP通信就要断开一次TCP连接
很早以前的通信情况来说,因为都是些容量很小的文本传输,所以这样也没有多大问题,可随着HTTP的普及,文档中包含大量图片的情况多了起来。
比如,使用浏览器浏览一个包含多张图片的HTML页面时,在发送请求访问HTML页面资源的同时,也会请求该HTML页面里包含的其他资源。因此,每次的请求都回造成无谓的TCP连接建立和断开,增加通信量的开销。
我们举一个实际的例子:
当我们在浏览器中输入:新闻
现在的HTTP协议在处理这个问题时,正常加载网站过程是先加载网页文档,就是原生的HTML代码,对应下面我们请求网站时的第一条记录,然后再一次次请求图片和js,服务端响应返回这些内容,这些js调用了后台的接口,拿到数据,再把网页完整的加载出来。
那么怎么解决这个问题,怎么保持连接状态,进行多次请求和响应?
HTTP/1.1和一部分的HTTP/1.0想出了持久连接(HTTP Persistent Connections),也称为HTTP keep-alive 或HTTP connection reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则要保持TCP连接状态
持久连接旨在建立1次TCP连接后进行多次请求和响应的交互
管线化
持久连接使得多数请求以管线化方式发送成为可能。从前发送请求后需要等待并收到响应,才能发送下一个请求。管线化计划出现后,不用等待响应亦可直接发送下一个请求。
这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。
不需要等待响应,直接发送下一个请求。
8.使用Cookie的状态管理
HTTP是无状态协议,它不对之前发生的请求和响应的状态进行管理和持久化处理。
也就是说,无法根据之前的状态进行本次的请求处理
假设要求登陆认证的Web页面本身无法进行状态管理(不记录登陆的状态),那么每次跳转新页面不是要再次登陆,就是要在每次请求报文附加参数来管理登陆状态。
无状态协议也有优点,由于不必保存状态,自然可减少服务器的CPU及内存资源的消耗。
但是如果让服务器管理全部客户端状态则会成为负担。
保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了Cookie技术。
Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。
当客户端发送请求,服务端收到后,发出响应,在响应报文内有一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下一次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发出去,这样服务器就能识别出客户端。
上图展示了发生Cookie交互的情景,HTTP请求报文和响应报文内容如下: