目录
[(2)TCP 四次挥手](#(2)TCP 四次挥手)
一、URL和URI
URI:全称为Uniform Resource Identifier,即统一资源标识符。
URL:全称为Universal Resource Locator,即统一资源定位符。
URL是URI的子集,也就是说每个URL都是URI,但并非每个URI都是URL,因为URI还包括一个子类,叫做URN,其全称为Universal Resource Name,即统一资源名称。URN只为资源命名而不指定如何定位资源,例如urn:isbn:0451450523指定了一本书的ISBN,可以唯一标识这一本书,但没有指定到哪里获取这本书,这就是URN。
URI、URL和URN关系图
但URL也不是随便写的,它也是需要遵循一定格式规范的,基本的组成格式如下:
scheme://[username:password@]hostname[:port][/path][;parameters][? query][#fragment]
其中,中括号包括的内容代表非必要部分,比如 https://www.baidu.com 这个URL,这里就只包含了scheme 和 hostname 两部分,没有 port、path、parameters、query、fragment。这里我们分别介绍一下几部分代表的含义和作用。
**□scheme:协议。**常用的协议有http、https、ftp等,另外scheme 也被常称作protocol,二者都\代表协议的意思。
**□usemame、password:**用户名和密码。在某些情况下 URL 需要提供用户名和密码才能访问,这时候可以把用户名和密码放在host前面。比如 https://ssr3.scrape.center 这个URL需要用户名和密码才能访问,直接写为 https://admin:admin@ssr3.scrape.center 则可以直接访问。
**□hostname:主机地址。**可以是域名或IP 地址,比如 https://www.baidu.com 这个URL中的这就是百度的二级域名。比如 https://8.8.8.8 这个 URL 中的hostname就是 8.8.8.8, 它是一个 IP 地址。
□port:端口。这是服务器设定的服务端口,比如 https://8.8.8.8:12345 这个URL中的端口就是12345。但是有些URL 中没有端口信息,这是使用了默认的端口。http协议的默认端口是80,https:协议的默认端口是443。所以 https://www.baidu.com https://www.baidu.com:443,而 http://www.baidu.com http://www.baidu.com:80。
**□path:路径。**指的是网络资源在服务器中的指定地址,比如 https://github.com/favicon.ico 中的path就是 favicon. ico,指的是访问GitHub根目录下的favicon. ico。
**□parameters:参数。**用来指定访问某个资源时的附加信息,比如 https://8.8.8.8:12345/hello;user 中的user就是 parameters。但是 parameters现在用得很少,所以目前很多人会把该参数后面的query部分称为参数,甚至把parameters 和query混用。严格意义上来说, parameters是分号()后面的内容。
**□query: 查询。**用来查询某类资源,如果有多个查询,则用&隔开。query其实非常常见,比如 https://www.baidu.com/s?wd=nba\&ie=utf-8, 其中的query部分就是wd=nba&ie=utf-8,这里指定了 wd是 nba, ie 是 utf-8。由于 query 比刚才所说的 parameters使用频率高很多,所以平时我们见到的参数、GET 请求参数、parameters、params 等称呼多数情况指代的也是 query。从严格意义上来说,应该用 query来表示。
**□fragment:片段。**它是对资源描述的部分补充,可以理解为资源内部的书签。目前它有两个主要的应用,一个是用作单页面路由,比如现代前端框架 Vue、React都可以借助它来做路由管理;另外一个是用作 HTML 锚点,用它可以控制一个页面打开时自动下滑滚动到某个特定的位置。
二、HTTP和HTTPS
HTTP的全称是Hypertext Transfer Protocol,中文名为超文本传输协议,其作用是把超文本数据从网络传输到本地浏览器,能够保证高效而准确地传输超文本文档。HTTP是由万维网协会( World WideWeb Consortium)和 Internet 工作小组 IETF(Internet Engineering Task Force)合作制定的规范, 目前被人们广泛使用的是 HTTP 1.1版本,当然,现在也有不少网站支持HTTP 2.0。
HTTPS 的全称是Hypertext Transfer Protocol over Secure Socket Layer,是以安全为目标的HTTP通道,简单讲就是 HTTP的安全版,即在HTTP下加入SSL层,简称HTTPS。
HTTPS 的安全基础是 SSL,因此通过该协议传输的内容都是经过 SSL加密的, SSL 的主要作用有以下两种。
□建立一个信息安全通道,保证数据传输的安全性。
□确认网站的真实性。凡是使用了 HTTPS协议的网站,都可以通过单击浏览器地址栏的锁头标志来查看网站认证之后的真实信息,此外还可以通过CA机构颁发的安全签章来查询。
现在有越来越多的网站和App朝着 HTTPS 的方向发展,举例如下。
□苹果公司强制所有iOS App在2017年1月1 日前全部改为使用HTTPS 加密,否则 App无法在应用商店上架。
□谷歌从 2017年1月推出的Chrome 56开始,对未进行 HTTPS 加密的网址亮出风险提示,即在地址栏的显著位置提醒用户"此网页不安全"。
□ 腾讯微信小程序的官方需求文档要求后台使用HTTPS请求进行网络通信,不满足条件的域名和协议无法正常请求。HTTPS已然是大势所趋。
注: HTTP和 HTTPS 协议都属于计算机网络中的应用层协议,其下层是基于TCP协议实现的,TCP协议属于计算机网络中的传输层协议,包括建立连接时的三次握手和断开时的四次挥手等过程。
(1)HTTP
**协议:**数据在网络上从源头到达目的地,网络通信的参与方必须遵循相同的规则。
超文本传输协议(HTTP): 服务器传输超文本到本地浏览器的传输协议;应用层协议,基于TCP/IP通信协议传输数据。HTTP协议是以明文方式 发送信息,一旦被截取传输报文,就可以直接获得其中信息。
目的: 提供一种发布和接收HTML页面的方法,使浏览器更加高效。
原理:
①客户端浏览器通过网络与服务器构建连接,一般是TCP来完成,建立连接后,客户机发送请求给服务器。
②服务器接到请求后,返回响应信息(格式为一个状态行)。
**请求格式:**统一资源标识符(url),协议版本号,MIME(请求修饰符,客户机信息和许可内容)。
**状态行:**信息的协议版本号,成功或错误的代码,MIME信息包。
**MIME信息包:**服务器信息,实体内容和可能的内容。
(2)HTTPS
HTTPS协议: 以安全为目标的HTTP通道,是HTTP的安全版,安全基础为SSLSSL协议:位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。
SSL协议 :安全套接层。 网络安全协议为网络通信提供安全及数据完整性的一种安全协
议,TL与SSL在传输层与应用层之间的网络连接进行加密。SSL协议由底层:SSL记录协议(SSL record Protocol)和高层:SSL握手协议(SSL Handshake Protocol)构成。
作用: 用于web浏览器与服务器之间的身份认证 和加密数据传输
SSL记录协议: 建立在可靠的传输协议(T4之类)为高层协议提供数据封装,压缩,加密 等基本功能的支持。
SSL握手协议: 建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证,协商加密算法,交换加密密钥 等。
设计目标:
①数据保密性: 保证数据内容在传输过程中不会被第三方查看。
②数据完整性: 及时发现被第三六篡改的传输内容。
**③身份校验安全性:**客户端和服务器在传输数据之前,会对双方进行身份认证,确认公钥是否由自己信任的证书签发机构签发,防止中间人攻击。
(3)HTTP与HTTPS区别
①HTTPS协议需要Ca申请证书,一般免费证书较少,因而需要一定的费用。
②HTTP是超文本传输协议,信息是明文发送传输,HTTPS是具有安全性的SSL加密传输协议。
③HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,HTiP端口为80,HTTPS端口为443。
⑤HTip的连接很简单,是无状态的,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输身份认证的网络协议,比HTTP协议安全。
无状态: 数据包的发送、传输和接收都是相互独立的。
**无连接:**通信双方都不长久的维持对方的任何信息。
(4)HTTPS对HTTP的改进:双问的身份认证
具体流程:
①客户端发起SSL握手信息给服务端要求连接。
②服务端将证书发送客户端。
③客户端检查服务端证书,确认证书是否由信任的证书签发机构签发(如果不是,将是否继续通信的决定权交给用户(安全缺陷)如果检查无误或用户选择继续通信,则客户端认可服务端身份)。
④服务端要求安户端发送证书,并检查是否通过验证(失败则关闭连接),认证成功则从客户端证书中获得客户端的公钥,一般为1024或2048位。
三、TCP协议
(1)TCP三次握手:
三次握手指建立一个TCP连接时,需要客户端和服务器总共发送3个包
**主要作用:**为了确认双方的接收能力和发送能力是否成,指定自己的初始化序列号后面的可靠性传输做准备。实质是连接服务器指定端口,建立TCP连接,刚开始客户端仅处于closed的状态,服务端处于listen状态。
**第一次握手:**客户端给服务端发一个SYN报文,并于自明客户端的初始化序列号ISN此时客户端处于SYN_SENT状态首部的同步位SYN=1,初始序号 seq=X,SYN=1的报文不能携带数据,但要消耗掉一个序号。
**第二次握手:**服务器收到客户端的SYN报文之后,会以自己的SY从报文作为应答,并且也是指定了自己的初始化序列号ISN(S)。同时会把客户端的ISN+1作为ACK的值,表示自己已经收到了客户端的SYN,此时服务器处于SYN_RCVD的状态。在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始号为Seq=Y。
**第三次握手:**客户端收到SYN报文之后,会发送一个ACK报文。当然也是一样把服务器的ISN+1作为ACK的值,表示已经收到服务端的SYN报文,此时客户端处于ESTABLISHED状态服务器收到Ack报文之后,也处于ESTABLISHED状态。
此时,双方已建立超起了连接。确认报文段A(k=1,确认号ack=y+1,序号Seq=x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号。发送第一个SYN的一端将执行主动打开(active open)接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)。
在socket编程中,客户端执行connect()时将触发三次握手
(2)TCP 四次挥手
TCP协议包结构:
①序号(Sequence number):给数据进行排序,TCP连接中,为传送的字节流(数据)中的每一个字节按顺序编号。从TCP连接建立的开始,到TCP连接的断开,要传的所有数据的每一个字节都要编号。
②ACK:TCP协议报文中的标志比特位,如果置1表示这个报文段是一个回复确认报文。
③FIN:TCP协议报文中的标志比特位,如果置表示这个报文段是用来迷天开TCP连接的。
④确认号(Acknowledge number):TCP传输的对端通过回复一个确认号,来表示确认收到某个ICP段。
第一次挥手: A的应用程序先向其TCP发出连接释放报文段,并停止发送数据,关闭TCP连接。A把连接释放报文段首部的FIN置1,其序列号seq=x。这时A进 入**FIN_WAIT-1**状态,等待B的确认。
注意: TCP规定,FIN报文段即使不携带数据,它也要消耗一个序号。
第二次挥手: B收到连接释放报文段后即发出确认,确认号是ack=x+1,序号为seq=y。然后B就进入**CLOSED-WAIT(关闭等待)**状态。TCP服务器进程这时应通知高层进程,因而从A到B这个方向的连接就释放了,这时TCP连接处于半关闭状态即A已经没有数据要发送了,但B若发送数据,A仍接收。也就是说,从B到A这个方向的连接并未关闭。这个状态可能会持续一些时间。A收到来自B的确认后,进入**FIN_WAIT_2(终止等待2)**状态,等待B发出的连接释放报文段。
第三次挥手: 要若B已经没有向A发送的数据了,其进和就会通知TCP释放连接。这时,B发出的连接释放报文段需要置FIN=1现假定B的序号为Z(在关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号. uck=x+1。这时B就进入了2AST---ACK(最后确认状态),等待A的确认。
第四次挥手: A在收到B的连续释放报文段后,必须对此发出确认。在确认板文段中把ACK置1,确认号ack=2+1,而自己的序号是Seq=u+1(根据T4标准,前面发送过的FIN报文段要消耗一个序号)然后进入到TIME_WAIT (时间等待)状态。
**注意:**此时TCP连接还没有释放掉,必须经过时间等待计时器设置的时间2MSL(MSL:最长报文寿命)后,A才进入到CLOSED状态。
四、HTTP请求过程
在浏览器地址栏中输入一个URL,按下回车之后便可观察到对应的页面内容。实际上,这个过程是浏览器先向网站所在的服务器发送一个请求,网站服务器接收到请求后对其进行处理和解析,然后返回对应的响应,接着传回浏览器。由于响应里包含页面的源代码等内容,所以浏览器再对其进行解析,便将网页呈现出来。客户端代表我们自己的电脑或手机浏览器,服务器就是要访问的网站所在的服务器。
为了更直观地说明上述过程,这里用Chrome浏览器开发者模式下的 Network监听组件来做一下演示。Network监听组件可以在访问当前请求的网页时,显示产生的所有网络请求和响应。 打开Chrome浏览器,访问百度,这时候单击鼠标右键并选择"检查"菜单(或者直接按快捷键F12)即可打开浏览器的开发者工具。
我们切换到Network面板,然后重新刷新网页,这时候就可以看到在Network面板下方出现了很多个条目,其中一个条目就代表一次发送请求和接收响应的过程。
我们先观察第一个网络请求,其中各列的含义如下。
**Name:**请求的名称。一般会用URL 的最后一部分内容作为名称。
**Status:响应的状态码。**这里显示为200,代表响应是正常的。通过状态码, 我们可以判断发送请求之后是否得到了正常的响应。
**Type:请求的文档类型。**这里为 document,代表我们这次请求的是一个 HTML 文档,内容是一些 HTML 代码。
**Initiator:请求源。**用来标记请求是由哪个对象或进程发起的。
**Size:从服务器下载的文件或请求的资源大小。**如果资源是从缓存中取得的,则该列会显示 from cache。
Time :从发起请求到获取响应所花的总时间。
**Waterfall:**网络请求的可视化瀑布流。我们单击这个条目,即可看到其更详细的信息。
我们单击这个条目,即可看到其更详细的信息,如图所示。
首先是General 部分,其中Request URL 为请求的URL, Request Method 为请求的方法, Status Code为响应状态码, Remote Address为远程服务器的地址和端口, Referre r Policy 为Referrer判别策略。
继续往下可以看到Response Headers 和 Request Headers, 分别代表响应头和请求头。请求头中包含许多请求信息,如浏览器标识、Cookie、Host等信息,这些是请求的一部分, 服务器会根据请求头里的信息判断请求是否合法,进而做出对应的响应。响应头是响应的一部分,其中包含服务器的类型、文档类型、日期等信息,浏览器在接收到响应后,会对其进行解析, 进而呈现网页内容。
五、请求
请求,英文为 Request,由客户端发往服务器,分为四部分内容:请求方法(Request Method)、请求的网址(Request URL )、请求头(Request Headers)、请求体(Request Body)。下面我们分别予以介绍。
(1)请求方法
请求方法,用于标识请求客户端请求服务端的方式,常见的请求方法有两种: GET和POST
在浏览器中直接输入URL 并回车,便发起了一个GET 请求,请求的参数会直接包含到URL里。例如,在百度搜索引擎中搜索Python就是一个GET 请求,链接为https://www.baidu.com/swd=Python,其中URL中包含了请求的query信息,这里的参数wd表示要搜寻的关键字。POST请求大多在提交表单时发起。例如,对于一个登录表单,输入用户名和密码后,单击"登录"按钮,这时通常会发起一个POST 请求,其数据通常以表单的形式传输,而不会体现在URL中。
GET 和POST 请求方法有如下区别。
□GET 请求中的参数包含在URL里面,数据可以在 URL中看到;而POST请求的 URL不会包含这些数据,数据都是通过表单形式传输的,会包含在请求体中。
□GET请求提交的数据最多只有1024字节,POST 方式则没有限制。
登录时一般需要提交用户名和密码,其中密码是敏感信息,如果使用 GET 方式请求,密码就会暴露在URL里面,造成密码泄露,所以这时候最好以POST 方式发送。上传文件时,由于文件内容比较大,因此也会选用POST 方式。
我们平常遇到的绝大部分请求是 GET 或 POST 请求。其实除了这两个,还有一些请求方法,如HEAD、PUT、DELETE、CONNECT、OPTIONS、TRACE等,我们简单将请求方法总结为下表。
|---------|---------------------------------|
| 方法 | 描述 |
| GET | 请求页面,并返回页面内容 |
| POST | 大多用于提交表单或上传文件,数据包含在请求体中 |
| HEAD | 类似于GET请求,只不过返回的响应中没有具体内容。用于获取报头 |
| PUT | 用客户端传向服务端的数据取代指定文档中的内容 |
| DELETE | 请求服务器删除指定的页面 |
| CONNECT | 把服务器当作跳板,让服务器代替客户端访问其他网页 |
| OPTIONS | 允许客户端查看服务器的性能 |
| TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
[请求方法]
(2)请求的网址
请求的网址,它可以唯一确定客户端想请求的资源。关于 URL 的构成和各个部分的功能我们在前文已经提及了,这里就不再赘述。请求头 请求头,用来说明服务器要使用的附加信息,比较重要的信息有Cookie、Referer、User-Agent等。下面简要说明一些常用的请求头信息。
□Accept:请求报头域,用于指定客户端可接受哪些类型的信息。
□Accept-Language:用于指定客户端可接受的语言类型。
□Accept-Encoding:用于指定客户端可接受的内容编码。
□Host:用于指定请求资源的主机IP和端口号,其内容为请求URL的原始服务器或网关的位置。从 HTTP 1.1版本开始,请求必须包含此内容。
□Cookie:也常用复数形式 Cookies, 这是网站为了辨别用户,进行会话跟踪而存储在用户本地的数据。它的主要功能是维持当前访问会话。例如,输入用户名和密码成功登录某个网站后,服务器会用会话保存登录状态信息,之后每次刷新或请求该站点的其他页面,都会发现处于登录状态,这就是 Cookie 的功劳。Cookie 里有信息标识了我们所对应的服务器的会话,每次浏览器在请求该站点的页面时,都会在请求头中加上 Cookie 并将其发送给服务器,服务器通过Cookie 识别出是我们自己,并且查出当前状态是登录状态,所以返回结果就是登录之后才能看到的网页内容。
□Referer: 用于标识请求是从哪个页面发过来的,服务器可以拿到这一信息并做相应的处理,如做来源统计、防盗链处理等。
□User-Agent:简称UA,这是一个特殊的字符串头,可以使服务器识别客户端使用的操作系统及版本、浏览器及版本等信息。做爬虫时如果加上此信息,可以伪装为浏览器;如果不加,很可能会被识别出来。
□Content-Type:也叫互联网媒体类型(Internet Media Type) 或者 MIME类型, 在 HTTP 协议消息头中,它用来表示具体请求中的媒体类型信息。例如, text/html代表 HTML格式, image/gif代表 GIF 图片, application/json代表 JSON 类型。请求头是请求的重要组成部分,在写爬虫时,通常都需要设定请求头。
(3)请求体
请求体,一般承载的内容是POST请求中的表单数据,对于 GET请求,请求体为空。
登录之前,需要先填写用户名和密码信息,登录时这些内容会以表单数据的形式提交给服务器,此时需要注意 Request Headers中指定Content-Type为 application/x-www-form-urlencoded。只有这样设置Content-Type,内容才会以表单数据的形式提交。另外,也可以将Content-Type设置为 application/json来提交 JSON数据,或者设置为 multipart/form-data来上传文件。
|-----------------------------------|-------------|
| Content-Type | POST提交数据的方式 |
| application/x-www-from-urlencoded | 表单数据 |
| multipart/from-data | 表单文件上传 |
| application/json | 序列化JSON数据 |
| text/xml | XML数据 |
[Content-Type和POST提交数据方式的关系]
在爬虫中,构造 POST 请求需要使用正确的Content-Type,并了解设置各种请求库的各个参数时使用的都是哪种Content-Type,如若不然可能会导致POST提交后无法得到正常响应。
六、响应
(1)响应
响应,即Response,由服务器返回给客户端,可以分为三部分:响应状态码(Response Status Code )、响应头(Response Headers)和响应体(Response Body)。响应状态码 响应状态码,表示服务器的响应状态,如200代表服务器正常响应、404代表页面未找到、500代表服务器内部发生错误。在爬虫中,我们可以根据状态码判断服务器的响应状态,如状态码为 200,证明成功返回数据,可以做进一步的处理,否则直接忽略。
一般来说:
1xx:临时响应
2xx:成功处理
3xx:进一步操作
4xx:可能会出错(请求)
5xx:服务器出现错误
|-----|-----------|-------------------------------------|
| 状态码 | 说明 | 详情 |
| 100 | 继续 | 请求者应当继续提出请求。服务器已接收到请求的一部分,正在等待其他部分。 |
| 101 | 切换协议 | 请求者已要求服务器切换协议,服务器已确认并准备切换 |
| 200 | 成功 | 服务器已成功处理了请求 |
| 201 | 已创建 | 请求成功并且服务器创建了新的资源 |
| 202 | 已接收 | 服务器已接收请求,但尚未处理 |
| 203 | 非授权信息 | 服务器成功处理了请求,但返回的信息可能来自另外一个源 |
| 204 | 无内容 | 服务器成功处理了请求,但没有返回任何内容 |
| 205 | 重置内容 | 服务器成功处理了请求,内容被重置 |
| 206 | 部分内容 | 服务器成功处理了部分请求 |
| 300 | 多钟选择 | 针对请求,服务器可执行多种操作 |
| 301 | 永久移动 | 请求的网页已永久移动到新位置,即永久重定向 |
| 302 | 临时移动 | 请求的网页暂时跳转到其他页面,即暂时重定向 |
| 303 | 查看其它位置 | 如果原来的请求是POST,重定向目标文件应该通过GET提取 |
| 304 | 未修改 | 此次请求返回的网页未经修改,继续使用上次的资源 |
| 305 | 使用代理 | 请求者应该使用代理访问该网页 |
| 307 | 临时重定向 | 临时从其他位置响应请求的资源 |
| 400 | 错误请求 | 服务器无法解析该请求 |
| 401 | 未授权 | 请求没有进行身份验证或验证未通过 |
| 403 | 禁止访问 | 服务器拒绝此请求 |
| 404 | 未找到 | 服务器找不到请求的网页 |
| 405 | 方法禁用 | 服务器禁用了请求中指定的方法 |
| 406 | 不接收 | 无法使用请求的内容响应请求的网页 |
| 407 | 需要代理授权 | 请求者需要使用代理授权 |
| 408 | 请求超时 | 服务器请求超时 |
| 409 | 冲突 | 服务器在完成请求时发生冲突 |
| 410 | 已删除 | 请求的资源已永久删除 |
| 411 | 需要有效长度 | 服务器不接收不含有有效内容长度标头字段的请求 |
| 412 | 未满足前提条件 | 服务器未满足请求者在请求中设置的某一个前提条件 |
| 413 | 请求实体过大 | 请求实体过大,超出服务器的处理能力 |
| 414 | 请求URL过长 | 请求网址过长,服务器无法处理 |
| 415 | 不支持类型 | 请求格式不被请求页面支持 |
| 416 | 请求范围不符 | 页面无法提供请求的范围 |
| 417 | 未满足期望值 | 服务器未满足期望请求标头字段的要求 |
| 500 | 服务器内部错误 | 服务器遇到错误,无法完成请求 |
| 501 | 未实现 | 服务器不具备完成请求的能力 |
| 502 | 错误网关 | 服务器作为网关或代理,接收到上游服务器的无效响应 |
| 503 | 服务不可用 | 服务器目前无法使用 |
| 504 | 网关超时 | 服务器作为网管或代理,没有及时从上游服务器接到请求 |
| 505 | HTTP版本不支持 | 服务器不支持请求中使用的HTTP协议版本 |
[常见的错误状态码及其错误原因]
(2)响应头
响应头,包含了服务器对请求的应答信息,如Content-Type、Server、Set-Cookie等。下面简要说明一些常用的响应头信息。
Date:用于标识响应产生的时间。
Last-Modified: 用于指定资源的最后修改时间。
Content-Encoding: 用于指定响应内容的编码。
Server:包含服务器的信息,例如名称、版本号等。
Content-Type: 文档类型,指定返回的数据是什么类型, 如 text/html代表返回HTML 文档,application/x-javascript代表返回JavaScript文件, image/jpeg代表返回图片。
Set-Cookie:设置Cookie。响应头中的 Set-Cookie 用于告诉浏览器需要将此内容放在Cookie 中,下次请求时将Cookie 携带上。
Expires:用于指定响应的过期时间,可以让代理服务器或浏览器将加载的内容更新到缓存中。当再次访问相同的内容时,就可以直接从缓存中加载,达到降低服务器负载、缩短加载时间的目的。
(3)响应体
Response 响应体,这可以说是最关键的部分了,响应的正文数据都存在于响应体中, 例如请求网页时,响应体就是网页的HTML代码;请求一张图片时,响应体就是图片的二进制数据。我们做爬虫请求网页时,要解析的内容就是响应体, 如下图所示。
在浏览器开发者工具中单击Preview, 就可以看到网页的源代码,也就是响应体的内容,这是爬虫的解析目标。在做爬虫时,我们主要通过响应体得到网页的源代码、JSON 数据等,然后从中提取相应内容。
七、HTTP2.0
HTTP协议从 2015 年起发布了2.0版本,相比HTTP 1.1 来说,HTTP 2.0变得更快、更简单、更稳定。HTTP2.0在传输层做了很多优化,它的主要目标是通过支持完整的请求与响应复用来减少延迟,并通过有效压缩HTTP请求头字段的方式将协议开销降至最低, 同时增加对请求优先级和服务器推送的支持,这些优化一笔勾销了HTTP 1.1为做传输优化想出的一系列"歪招"。有读者这时候可能会问,为什么不叫HTTP 1.2 而叫 HTTP 2.0 呢? 因为 HTTP 2.0内部实现了新的二进制分帧层,没法与之前HTTP 1. x的服务器和客户端兼容,所以直接修改主版本号为 2.0。下面我们就来了解一下HTTP 2.0相比HTTP 1.1来说,做了哪些优化。
(1)二进制分帧层
HTTP 2.0 所有性能增强的核心就在于这个新的二进制分帧层。在 HTTP 1. x中,不管是请求(Request)还是响应(Response), 它们都是用文本格式传输的, 其头部(Headers)、实体(Body)之间也是用文本换行符分隔开的。HTTP2.0对其做了优化,将文本格式修改为了二进制格式使得解析起来更加高效。同时将请求和响应数据分割为更小的帧,并采用二进制编码。所以这里就引入了几个新的概念。
□**帧:**只存在于 HTTP 2.0中的概念,是数据通信的最小单位。比如一个请求被分为了请求头帧(Request Headers Frame) 和请求体/数据帧(Request Data Frame)。
□数据流:一个虚拟通道,可以承载双向的消息,每个流都有一个唯一的整数ID来标识。
□**消息:**与逻辑请求或响应消息对应的完整的一系列帧。
在 HTTP 2.0中,同域名下的所有通信都可以在单个连接上完成,该连接可以承载任意数量的双向数据流。数据流是用于承载双向消息的,每条消息都是一条逻辑 HTTP消息(例如请求或响应),它可以包含一个或多个帧。
简而言之, HTTP2.0将HTTP协议通信分解为二进制编码帧的交换,这些帧对应着特定数据流中的消息,所有这些都在一个ICP连接内复用。这是 HTTP2.0协议所有其他功能和性能优化的基础。
(2)多路复用
在HTTP1x中,如果客户端想发起多个并行请求以提升性能,则必须使用多个TCP连接,而且浏览器为了控制资源,还会对单个域名有6~8个TCP连接请求的限制。但在HTTP2.0中,由于有了二进制分帧技术的加持, HTTP 2.0不用再以 TCP 连接的方式去实现多路并行了,客户端和服务器可以将HTTP消息分解为互不依赖的帧,然后交错发送,最后再在另一端把它们重新组装起来,达到以下效果。
□并行交错地发送多个请求,请求之间互不影响。
□并行交错地发送多个响应,响应之间互不干扰。
□使用一个连接并行发送多个请求和响应。
□不必再为绕过 HTTP 1. x限制而做很多工作。
□消除不必要的延迟和提高现有网络容量的利用率,从而减少页面加载时间。
这样一来,整个数据传输性能就有了极大提升。
□同域名只需要占用一个TCP连接,使用一个连接并行发送多个请求和响应,消除了多个TCP连接带来的延时和内存消耗。
□并行交错地发送多个请求和响应,而且它们之间互不影响。
□在HTTP 2.0中,每个请求都可以带一个31位的优先值,0表示最高优先级,数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略了,以最优的方式发送流、消息和帧。
(3)流控制
流控制是一种阻止发送方向接收方发送大量数据的机制,以免超出后者的需求或处理能力。可以理解为,接收方太繁忙了,来不及处理收到的消息了,但是发送方还在一直大量发送消息,这样就会出现一些问题。比如,客户端请求了一个具有较高优先级的大型视频流,但是用户已经暂停观看视频了,客户端现在希望暂停或限制从服务器的传输,以免提取和缓冲不必要的数据。再比如,一个代理服务器可能具有较快的下游连接和较慢的上游连接,并且也希望调节下游连接传输数据的速度以匹配上游连接的速度,从而控制其资源利用率等。
HTTP是基于TCP实现的,虽然TCP原生有流控制机制,但是由于HTTP2.0数据流在一个TCP连接内复用,TCP流控制既不够精细, 也无法提供必要的应用级 API来调节各个数据流的传输。
为了解决这一问题, HTTP2.0提供了一组简单的构建块,这些构建块允许客户端和服务器实现它们自己的数据流和连接级流控制。
□流控制具有方向性。每个接收方都可以根据自身需要选择为每个数据流和整个连接设置任意的窗口大小。
□流控制的窗口大小是动态调整的。每个接收方都可以公布其初始连接和数据流流控制窗口(以字节为单位),当发送方发出DATA 帧时窗口减小,在接收方发出WINDOW_UPDATE 帧时窗口增大。
□流控制无法停用。建立HTTP2.0连接后,客户端将与服务器交换SETTINGS帧,这会在两个方向上设置流控制窗口。流控制窗口的默认值设为65535字节,但是接收方可以设置一个较大的最大窗口大小(2³¹-1 字节),并在接收到任意数据时通过发送WINDOW_UPDATE 帧来维持这一大小。
□由此可见,HTTP 2.0 提供了简单的构建块,实现了自定义策略来灵活地调节资源使用和分配逻辑,同时提升了网页应用的实际性能和感知性能。
(4)服务端推送
HTTP 2.0新增的另一个强大的功能是:服务器可以对一个客户端请求发送多个响应。换句话说,除了对最初请求的响应外,服务器还可以向客户端推送额外资源,而无须客户端明确地请求。
如果某些资源客户端是一定会请求的,这时就可以采取服务端推送的技术,在客户端发起一次请求后,提前给客户端推送必要的资源,这样就可以减少一点延迟时间。如图所示, 服务端接收到HTML 相关的请求时可以主动把JS和CSS文件推送给客户端,而不需要等到客户端解析HTML时再发送这些请求。
服务端推送
另外,主动推送也遵守同源策略,即服务器不能随便将第三方资源推送给客户端, 而必须是经过服务器和客户端双方确认才行,这样也能保证一定的安全性。