HTTP(HyperText Transfer Protocol)协议,超文本传输协议,是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。它位于OSI五层协议体系结构中的最上层,属于应用层协议。它定义了应用进程减通信和交互的规则。
同一资源定位符URL用来表示从因特网上得到资源的位置和访问这些资源的方法。这里所说的资源是指因特网上能够被访问的任何对象,包括文件目录、文件、文档、图片等等。URL的的一般形式如下:
<协议>:// <主机>:<端口>/<路径>
这里的协议就是指出了用什么协议来获取万维网文档,可以是http协议,也可以是ftp协议。主机指出了需要访问的资源文档位于万维网上的哪个主机,就是域名。端口就是通过DNS服务器解析出来的ip定位到主机后需要指定的进程号,http默认端口为80端口。路径就喜欢ixuyao访问的资源在服务器中的路径位置。
URI(同一资源标识符),它包含了URL,也就是说一个URL是一个URI,但是一个URI不一定是一个URL,URI中还有一个子集称为URN,它只命名资源而不定位资源。
HTTP协议定义了客户端怎样向万维网服务器发送请求以及服务器如何响应客户端的方式。从层次的角度上来讲,HTTP是面向事务的(transaction-oriented)应用层协议,它是万维网可靠交换文件的基础。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。我们来看看HTTP是怎样发送请求并接收文件的:
1、客户端请求连接到服务器: 每个万维网都有一个服务器进程,这个进程一直监听TCP的80端口,来发现是否有客户端向他发起请求。当发现有向他发起建立连接的请求,就建立起一个套接字TCP连接。
2、发送HTTP请求: 当建立起TCP连接后,客户端就通过套接字向服务器发送一个请求报文,这个报文包含了请求行、请求头、空行和请求数据4部分。
3、服务器接收请求并返回响应: 服务器首先解析客户端发送的报文然后定位到需要的资源,通过套接字将响应报文发送给客户端。同理一个响应也由状态行、响应头部、空行和响应数据4部分组成。
4、释放TCP连接: 如果请求头中connection字段为close则服务器立即关闭TCP连接,如果为keep-alive,则连接会持续一段时间后关闭。
5、客户端解析资源: 客户端会首先解析状态行,如果状态行成功,则解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
我们接下来看一个访问清华大学院系设置的例子来看看整个过程:URL为 http://www.tsinghua.edu.cn/chn/yxsz/index.htm
(1)、浏览器分析链接指向页面的URL
(2)、浏览器向DNS服务器请求解析域名对应的IP地址
(3)、DNS解析出IP地址后浏览器根据IP地址和默认的80端口与服务器建立TCP连接
(4)、浏览器发起取文件命令GET/chn/yxsz/index.htm,该请求作为TCP三次握手的第三个报文的数据发送给服务器
(5)、服务器作出响应并将文件发送给浏览器
(6)、释放TCP连接
(7)、浏览器解析数据并显示
&esmp; 因此我们可以看到http协议是基于TCP/IP协议之上的,我们通过一个图示来展示这个过程;
http的无状态是指,同一个客户端第二次访问该服务器上的相同资源时,返回的内容与上一次相同(假设服务器没有更新该页面)。也就是说HTTP协议自身不对请求和响应之间的通信状态进行保存。这样设计的原因在于能够大量地处理事物确保协议的可伸缩性。但是随着web技术的发展,这样特点的协议不能很好地满足业务的发展,例如我们登陆到某个网站时,当我们浏览该网站其他页面时我们也需要保持登陆状态,以便能够进行与服务器的交互。因此在http/1.1中虽然使用了无状态的特点,但是引入了cookies–session机制来支撑这种状态保持的需求。
无连接是指限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。在http/1.0中使用的就是这种方式,但是这种方式有缺点。从http请求和响应过程我们可以看到,请求一个万维网文档所需的时间是该文档的传输时间加上两倍的往返RTT(传输时延),其中一个RTT用于建立TCP连接,另一个RTT用于请求和接收万维网文档。因此一个请求的时间开销就有两倍RTT。如果一个主页上有很多连接对象需要依次连接,那么每一次连接都会有2倍RTT的开销。
因此在http/1.1中使用了持续连接(persistent connection),持续连接就是服务器在发送响应后仍然在一段时间内保持这条连接,这样同一个客户端就可以继续在这条连接上传输http请求报文和响应报文。如果在这段时间内客户端没有向服务器发送报文就断开这条连接。
持续连接有两种工作方式,分别为流水线方式和非流水线方式。
非流水线方式 是指客户端在收到前一个响应后才能发送下一个请求。因此在建立了TCP连接后,客户端每访问依次对象就要用去一个RTT,比起非持续连接节省了一个建立TCP连接的RTT时间。但是这种方式也有缺点,服务器在发送完一个对象后,这条TCP连接就处于空闲状态,浪费了服务器资源。
流水线方式 是指客户端在收到http报文之前就可以发送新的请求报文,因此多个请求报文到达服务器后,服务器就可以连续处理并发送响应报文。使用这种方式客户端访问所有对象只需要一个RTT时间,因此TCP的空闲时间减少,文档下载效率提高了。
开始行用于区分是请求报文还是响应报文,在请求报文中,开始行叫做请求行,在响应报文中,开始行为响应行,开始的三个字段用空格隔开。
http/1.1中定义了很多方法来指定对所请求对象的操作,常见的方法有GET和POST两种方法。它们的区别如下:
GET方法: 它的请求参数包含在URL里面,数据在URL中是可见的,而且GET方法请求提交的数据只能为1024个字节。
POST方法: POST请求的参数数据不包含在参数里面,而是通过请求体body传输的,可以想象如果你在登陆时将参数放在URL里面是不安全的。此外POST请求对提交的数据大小不做限制。
这个没什么可说的,就是你需要访问资源的URL。
就是使用的http协议的版本,例如http/1.1
响应行中的版本也是http协议所使用的版本;状态码就是当前响应的类型,如下:
1xx消息——请求已被服务器接收,继续处理
2xx成功——请求已成功被服务器接收、理解、并接受
3xx重定向——需要后续操作才能完成这一请求
4xx请求错误——请求含有词法错误或者无法被执行
5xx服务器错误——服务器在处理某个正确请求时发生错误
请求行用来说明服务器要使用的附加信息,下面列出了一些常用的请求行
Accept: 请求报头域,说明了客户端希望接收哪些类型的信息,例如 text/xml表示客户端希望接受的数据类型是xml类型,application/json代表客户端希望接收的数据类型是json类型。看一个例子:Accept:application/xml;q=0.5,application/json;q=0.9,text/html
将按照如下顺序进行produces的匹配 ①text/html ②application/json ③application/xml
参数为媒体类型的质量因子,越大则优先权越高(从0到1)
Accept-Language: 客户端希望接收的语言类型
Accept-Encoding: 客户端可接受的内容编码
Host: 用于指定请求资源的主机IP和端口
Cookie: 网站为了辨别用户会话进行会话跟踪而存储在本地的数据,它的主要功能是维持当前会话。我会在后面详细解释
Referer: 表示这个请求是从哪个页面发送过来的,服务器可以用这个信息来统计源和做防盗链。
User-Agent: 它可以是服务器知道客户端使用的操作系统及版本等等各种信息
Content-Type: MIME类型,在http协议中,表示发送端发送的实体数据的数据类型,具体类型可参考: https://tool.oschina.net/commons
Content-Length: 请求体里面的数据长度
在响应行中表明了对客户端的应答信息
Date: 标识响应产生的时间
Last-Modified: 指定资源最后修改的时间
Content-Type: 文档类型,指定返回的数据类型是什么
Content-Encoding: 指定响应内容的编码
Content-Length: 指定了返回的实体的长度,以字节为单位。
Server: 包含了服务器的信息,比如名称,版本号等等
Set-Cookies: 设置cookies,告诉浏览器需要将此内容放在cookies中,下一次携带这个参数
Expire: 指定响应过期的时间
请求体中一般承载的是POST请求中的表单数据,对于GET请求,请求体一般为空,对于POST请求中的数据大小,就位于请求头中的content-length字段中。需要注意的是在使用POST请求时,需要指定你所提交的数据是什么类型,也就是Content-Type字段中的值,因此在使用POST请求需要首先了解请求库中的请求体参数是什么类型的,然后设置请求头的字段,不然可能无法正常响应。
响应体是最重要的部分了,因为响应的正文数据都在响应体中,响应体中的数据也有不同的类型,因此我们写爬虫的时候就是解析的响应体里面的数据,通过解析HTML或者json数据来获取数据。响应体的数据也在content-type中指明了它的类型。
这里对于cookies和session可以参考这篇文章,讲解得比较爱哦详细,我就不再这里赘述了。cookie & session & token