Python 测试之道

ʕ •ᴥ•ʔ (๑˃̵ᴗ˂̵) ପ( ˘ᵕ˘ ) ੭

接口测试基础

从技术的角度来说,把用户发起请求之后的等待时间称为响应时间

1 网络传输知识

1.1 Cache

提高反应速度的方法常见的有使用缓存、CDN、优化网页内容加载等。最常用的是使用缓存Cache保存到本地。根据类型来分缓存分为:

  • 浏览器缓存
  • 代理缓存
  • 网关缓存

根据缓存策略来分:

  • 强缓存:直接从本地缓存中取资源,不会和服务器通信。
  • 协商缓存:通过服务器告知是否能用本地缓存。
    • 先和服务器通信,若返回可以使用本地缓存的指示,再从本地缓存取;
    • 如不可以使用本地缓存,就会返回最新的资源。

参考【阿里巴巴:浏览器的强缓存和协商缓存(一面)

缓存策略

IMG_9365.JPG

1.1.1 浏览器缓存

使用缓存 Cache 的站点会监听客户端向服务端发出的请求,并根据相应缓存设置保存服务器反馈的数据到本地主机,比如 HTML页面、图片等文件。当下次用户使用相同的 URL 发送请求,请求不会直接发向服务器,而是通过缓存策略先行判断是否使用之前已经保存下来的反馈文件,从而降低服务器的负载及提高数据的响应时间。这样可以节省上网流量。

1.1.2 代理缓存

由于客户端内存的限制,浏览器缓存不能存放过多的数据,否则会降低本机的性能。在实际应用中,开发者需要缓存大规模的数据及面向更广泛的用户群时,可以使用代理缓存(代理服务器),它使用相同的原理,但可以用相同的方法为几百甚至几千的使用者服务。总结来说代理缓存比浏览器缓存面向多用户及大规模数据

代理缓存是共享缓存的一种,不是只有一个人正在使用它们,而是同时存在大量的用户使用。

代理缓存既不属于客户端,也不属于服务器端,而是利用网络路由请求信息。有以下几种场景:

  • 用户手动设置浏览器的代理
  • 使用网页代理,网页代理将你的 URL 请求通过它潜在的网络定向到代理,所以用户甚至无需手动配置它们
1.1.3 网关缓存

网关缓存同样是充当代理的角色,同样起到代理缓存的作用,但是他和代理缓存是有区别的。网关可以为通信线路上的服务器提供不同的协议服务。加入上网线路为:

  • 代理缓存:$用户\dashrightarrow代理服务器\dashrightarrow服务器$ ,代理服务器与用户和服务器之间使用相同的通信协议

  • 网关缓存:$用户\dashrightarrow网关\dashrightarrow服务器$ ,网关与用户和服务器之间可以使用不相同的通信协议

网关缓存也是中间人,但不是由系统网络管理员处于节省带宽而部署,它们通常是网站站长部署的,使网站可扩展性、可靠性和性能更好,它可以将请求路由到网关高速缓存,类似于负载均衡器。

可以用来解决 无状态协议反复认证和身份认证的的特性。关于无状态协议和有状态协议:

此外还应该关注无连接协议,同时对应 HTTP 报文中的中的connect字段为aliveclose

用户浏览器访问一个支持 Cookie 的网站,会经过以下过程(1 2是首次请求访问时选择“保存用户名”,3 4是再次访问):

(1)客户端 --> 服务器

(2)客户端 (保存Cookie) <-- 服务器(Set-Cookie)

(3)客户端(Cookie) --> 服务器

(4)客户端 <-- 服务器

1.2.1 获取Cookie的途径
  1. 使用抓包工具,如 BurpSuite 等

  2. 浏览器检查网页请求能够获取Cookie

  3. 从本地文件中获取

    • IE 浏览器%APPDATA%\Microsoft\Windows\Cookies\ 目录中的xxx.txt文件(里面可能有很多个.txt Cookie文件)

    • Firefox%APPDATA%\Mozilla\Firefox\Profiles\ 目录中的xxx.default目录,名为cookies.sqlite的文件。在 Firefox 中查看 cookie,可以选择工具 > 选项 > 隐私 > 显示cookie

    • Chrome%LOCALAPPDATA%\Google\Chrome\User Data\Default\ 目录中,名为Cookies的文件。在 Chrome 中查看 cookie,可以选择设置 > 隐私设置和安全性 > Cookie 及其他网站数据 > 查看所有 Cookie 和网站数据

      在 IE 浏览器中,IE将各个站点的Cookie分别保存为一个XXX.txt这样的纯文本文件(文件个数可能很多,但文件大小都较小);而 Firefox 和 Chrome 是将所有的Cookie都保存在一个文件中(文件大小较大),该文件的格式为SQLite3数据库格式的文件。

  4. 通过前端技术获取

    • 可以在浏览器地址栏输入:javascript:alert(document.cookie)
1.2.2 Cookie的生命周期
  1. 默认情况下:Cookie 数据保存到内存里,当浏览器关闭后,Cookie数据被销毁
  2. 持久化存储: 根据setMaxAge(int seconds)函数的参数来设置:
  • 正数:将Cookie数据写到硬盘的文件中,持久化存储。并指定Cookie存活时间,时间到后,Cookie文件自动失效。
  • 负数:默认值,即关闭浏览器后,Cookie即失效
  • 零:删除Cookie信息,会马上在浏览器上删除指定的cookie

setMaxAge参数为正数时的情况如下:

cookie时间是否到期 重启浏览器 不关闭浏览器
cookie时间未到 能访问cookie 能访问cookie
cookie时间到 不能访问cookie 能访问cookie

修改 Cookie 的生命周期的方法:

  • 通过浏览器修改
  • 在服务器端的代码层面修改

Cookie 的常用属性:

  1. Name:Cookie 的名称。Cookie 一旦创建,名称便不可以修改。

  2. Value:Cookie 的值。如果值为Unicode字符,需要为字符编码,如果值为二进制数据,则需要使用base64编码

    • Unicode编码保存中文

      中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字 符,内存中只占2个字节。Cookie 中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。

    • Base64编码保存二进制图片

      Cookie 不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。例如,在Cookie中使用数字证书,提供安全度。使用二进制数据时需要进行Base64编码。

  3. Expires/Max-Age:Cookie 失效时间,单位为秒。

    • 如果为正数,该 Cookie 会在 MaxAge 秒之后自动失效。
    • 为0时表示立即删除Cookie。
    • 为负数,表示该 Cookie 为临时 Cookie,关闭浏览器即失效,默认值为-1
  4. Secure:该 Cookie 是否仅被使用安全传输协议传输。安全协议由 HTTPS、SSL等,在网络上传输数据之前先将数据加密,默认是false

  5. Path:该 Cookie 的使用路径。

  6. Domain:可以访问该 Cookie 的域名。如果设置为.google.com,则所有以google.com结尾的域名都可以访问该 Cookie(即它的子域名)。若当前网站是非顶级域名,如二级域名或者三级域名,设置的 Cookie 的domain只能为顶级域名或者二级域名或者三级域名本身,不能设置其他二级域名的 Cookie,否则 Cookie 无法生成。

  7. HttpOnly:Cookie 的HttpOnly 属性是 Cookie 的扩展功能,它使JavaScript 脚本无法获得 Cookie。其主要目的为防止跨站脚本攻击(Cross-sitescriptingXSS)对 Cookie 的信息窃取。

参考:

1.3 Session

Session 和 Cookie 一样是用来解决无状态协议的,不同的是 Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。

客户端访问网站带有 Session 的过程:

(1)客户端 --> 服务器

(2)客户端 <-- 服务器(Set-Session 并保存)

(3)客户端(Session) --> 服务器

(4)客户端 <-- 服务器

HTTP协议本身是”无状态”的,在一次请求和下一次请求之间没有任何状态保持,服务器无法识别来自同一用户的连续请求。有了cookie和session,服务器就可以利用它们记录客户端的访问状态了,这样用户就不用在每次访问不同页面都需要登录了。

什么是cookie,cookie的应用场景及缺点

cookie是一种数据存储技术, 它是将一段文本保存在客户端(浏览器或本地电脑)的一种技术,并且可以长时间的保存。当用户首次通过客户端访问服务器时,web服务器会发送给客户端的一小段信息。客户端浏览器会将这段信息以cookie形式保存在本地某个目录下的文件内。当客户端下次再发送请求时会自动将cookie也发送到服务器端,这样服务器端通过查验cookie内容就知道该客户端早访问过了。

Cookie 的常见应用场景包括:

  • 判断用户是否已经登录
  • 记录用户登录信息(比如用户名,上次登录时间)
  • 记录用户搜索关键词

Session 的常见应用场景包括:验证登录信息

Cookie的缺点在于其并不可靠不安全,主要原因如下:

  • 浏览器不一定会保存服务器发来的cookie,用户可以通过设置选择是否保存cookie。
  • cookie是有生命周期的(通过Expire设置),如果超过周期,cookie就会被清除。
  • HTTP数据通过明文发送,容易受到攻击,因此不能在cookie中存放敏感信息(比如信用卡号,密码等)。
  • cookie以文件形式存储在客户端,用户可以随意修改的。

什么是session及session的工作原理

session又名会话,其功能与应用场景与cookie类似,用来存储少量的数据或信息。但由于数据存储在服务器上,而不是客户端上,所以比cookie更安全。

Session工作的流程如下:

  • 客户端向服务器发送请求时,看本地是否有cookie文件。如果有,就在HTTP的请求头(Request Headers)中,包含一行cookie信息。
  • 服务器接收到请求后,根据cookie信息,得到sessionId,根据sessionId找到对应的session,用这个session就能判断出用户是否登录等等。

使用Session的好处在于,即使用户关闭了浏览器,session仍将保持到会话过期。

1.3.1 Session的传输
  • 通过 Cookie 传输
  • URL地址重写

Session 可以借助 Cookie 来传输,在 Cookie 中会有一个sessionID的键值对,他就是用来传输 Session 的。

一次打开浏览器时,session是可以多窗口共享的,子窗口可以使用符窗口的 Cookie,因此会共享一个 Session,但是重新打开浏览器(重新启动)会生成新的 Session。但是如果浏览器将 Cookie 功能禁用或者网站不支持 Cookie 时,这时候就不能够通过 Cookie 来传输 Session,所以就使用 URL 地址重写来进行 Session 的传输。

URL地址重写是对客户端不支持 Cookie 的解决方案。它的原理是将用户的 Session 的 ID 信息重写到 URL 地址中。服务器能够解析重写后的 URL,获取 Session 的 ID。 服务器会先自动判断客户端是否支持 Cookie。如果客户端支持,会将 URL 原封不动地输出,如果不支持,则会将 Session 的 ID 重写到 URL 中,重写后的 URL 可能是这样的:https://mp.weixin.qq.com/s?jsessionid=BYjhghj89HBbuhygG-145

1.3.2 Session的生命周期

需要区分开 Session 和 Session ID,Session 由服务器来进行存储,而且是存储在内存中,不过 Session 可以通过特殊的方式做持久化管理(memcache,redis)。Session ID 存放在服务器以及客户端的 Cookie 中,客户端中的 Session ID 用来和服务器进行会话认证。

服务器内存中有许多的 Session,可以用使用 Session ID 来找到 Session 对象,这就是使用 Session ID 来标志 Session 的作用。

  • 在创建了 Session 的同时,服务器会为该 Session 生成唯一的Session ID,而这个Session ID 在随后的请求中会被用来重新获得已经创建的Session;
  • 在 Session 被创建之后,就可以调用Session相关的方法往 Session 中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有SessionID;
  • 当客户端再次发送请求的时候,会将这个Session ID 带上,服务器接受到请求之后就会依据 Session ID 找到相应的 Session,从而再次使用之。

Session 和 Session ID 的删除:

  1. 当浏览器关闭时 Session ID 会删除而 Session 不会删除。
  2. Session 删除的几种方式:超时、程序调用HttpSession.invalidate()、服务器关机或重启(内存数据丢失)。

参考【Cookie和Session、SessionID的那些事儿

1.3.3 Cookie和Session的区别
  1. 存储位置不同

通常情况

  • Cookie 的数据信息存放在客户端浏览器上。
  • Session 的数据信息存放在服务器内存中。
  1. 存储容量不同

通常情况

  • 单个 Cookie 保存的数据≤ 4KB,一个站点最多保存20个 Cookie。
  • 对于 Session 并没有上限,但出于对服务器端的性能考虑,Session 内不要存放过多的东西,并且设置 Session 删除机制。
  1. 存取方式的不同
  • Cookie 中只能保管ASCII字符串,需要通过编码的方式存取Unicode字符或者二进制数据。运用 Cookie 难以实现存储略微复杂的信息。
  • Session中能够存取任何类型的数据,包括且不限于Sting、Integer、List、Map等。
  1. 隐私策略的不同
  • Cookie 对客户端是可见的,别有用心的人可以分析存放在本地的 Cookie 并进行Cookie欺骗,所以它是不安全的。
  • Session 存储在服务器上,对客户端是透明的,不存在敏感信息泄露的风险。

假如选用 Cookie,比较好的方法是:敏感的的信息,如账号密码等,尽量不要写到 Cookie中。可以将 Cookie 信息加密,提交到服多务器后再进行解密。存储在本地的 Cookie 就需要自行加密。

  1. 有效期上的不同
  • 开发可以通过设置 Cookie的属性,达到使Cookie长期有效的效果。
  • 由于Session依赖于名为JSESSIONID的 Cookie,而Cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该 Session 就会失效。因而 Session 不能达到长期有效的效果,就算不依顿于 Cookie,运用 URL 地址重写也不能完成,因为假如设置 Session 的超时时间过长,服务器累计的 Session 就会越多,越容易导致内存溢出。
  1. 服务器压力的不同
  • Session 是保管在服务器端内存中的,每个用户都会产生一个 Session。假如并发访问的用户很多,会产生很多的 Session,耗费大量的内存。
  • Cookie 保管在客户端,不占用服务器资源。对于并发用户很多的网站,Cookie 是很好的选择。
  1. 浏览器支持的不同

假如客户端浏览器不支持 Cookie。

  • Cookie 是需要客户端浏览器支持的。假如客户端禁用了 Cookie, 或者不支持 Cookie,则会话跟踪会失效。关于 WAP 上的应用,常规的 Cookie 就派不上用场了。
  • 运用 Session 需要使用URL地址重写的方式。一切用到 Session 程序的 URL 都要进行 URL 地址重写,否则Session 会话跟踪还会失效。关于 WAP 应用来说,Session+URL 地址重写或许是它唯一的选择。

假如客户端支持Cookie。

  • Cookie既能够设为本浏览器窗口以及子窗口内有效(把过期时间设为-1),也能够设为一切窗口内有效(把过期时间设为某个大于0的整数)。
  • Session 只能在本窗口以及其子窗口内有效。假如两个浏览器窗口互不相干,它们将运用两个不同的 Session(IE8 下不同窗口 Session 相干。)
  1. 跨域支持上的不同
  • Cookie支持跨城名访问,例如,将domain属性设置为.biaodianfu.com,则以 .biaodianfu.com为后缀的一切域名均能够访问该 Cookie。跨域名 Cookie 如今被普遍用在网络中,例如,Google、Baidu、Sina 等。
  • Session 则不会支持跨坡名访问。Session 仅在它所在的城名内有效。

1.4 Token

  • Session 是用来解决 Cookie 的安全性的问题的,那么 Token 就是用来解决 Session 消耗内存问题而提升性能的。
  • Token 是使用时间换取空间的方法,即 CPU 计算验证的时间换取内存存储 Session 的空间。
  • Token 受同源策略限制,而 Cookie 和 Session 不受同源策略限制,故 Token 能够防范 CSRF 攻击。

未命名文件.png

Token 的原理图如上图,可以概述为以下几点:

(1)客户端第一次请求时,发送用户信息到服务器。服务器收到用户信息并进行身份认证无误后,使用加密算法和密钥对用户信息进行签名,然后将被签名和数据作为 Token,返回给客户端。

(2)服务器端不保存 Token,客户端保存 Token

(3)客户端再次发送请求时,在请求的信息中将 Token 一起发送给服务器。

(4)服务器使用同样的加密算法和密钥对数据再进行一次签名,然后对比计算得到的签名和 Token 的签名做比较进行认证。

运用 Token 服务器就不再需要保存 Session 了,只需要生成 Token 然后认证 Token,这就是服务器利用 CPU 计算时间换取 Session存储空间的方式。Token 可以放在 Cookie 中,若客户端不支持 Cookie,Token 也可以放置在请求头中。

Token 通常用于一种轻巧的规范下,这种规范叫做 JOSN Web Token(JWT)。

Token可以抵抗CSRF,Cookie + Session不行?

假如用户正在登陆银行网页,同时登陆了攻击者的网页,并且银行网页未对csrf攻击进行防护。攻击者就可以在网页放一个表单,该表单提交src为http://www.bank.com/api/transfer,body为count=1000&to=Tom。倘若是session+cookie,用户打开网页的时候就已经转给Tom1000元了.因为form 发起的 POST 请求并不受到浏览器同源策略的限制,因此可以任意地使用其他域的 Cookie 向其他域发送 POST 请求,形成 CSRF 攻击。在post请求的瞬间,cookie会被浏览器自动添加到请求头中。但token不同,token是开发者为了防范csrf而特别设计的令牌,浏览器不会自动添加到headers里,攻击者也无法访问用户的token,所以提交的表单无法通过服务器过滤,也就无法形成攻击。

参考文章:

1.5 JOSN Web Token(JWT)

JOSN Web Token(JWT)是一种开放标准( RFC 7519),它定义了一种紧凑且安全的标准,用于将各方之间的信息传输为 JSON 对象。该信息通过数字简明进行校验。使用 HMAC 算法或者使用 RSA 的公钥/私钥对 JWT 进行检签名,但是在通信中为了提高通信的速度,所以一般使用对称密码算法进行数字签名。

JWT 由三部分组成:头部荷载签名

1.5.1 头部( Header )

头部用于描述关于 JWT 的最基本的信息,例如,其类型以及签名所用的算法等。它被表示成一个 JSON 对象。

1
2
3
4
{
"typ": "JWT",
"alg": "HS256"
}

在这里,我们说明了这是一个JWT,并且我们所用的签名算法是HS256算法。

对它进行Base64编码后形成的字符串就成了JWTheader (头部)。

1.5.2 载荷( Payload )

将添加好友的操作描述成一个JSON对象。其中添加了一些其他的信息,帮助今后收到这个JWT的服务器理解这个JWT

1
2
3
4
5
6
7
8
9
{
"iss": "Kathy Yang JWT",
"iat": 1455624102,
"exp": 1475632522,
"aud": "www.example.com",
"sub": "jrocket@example.com",
"Givename": "Smark",
"Surname": "Kathy"
}

这里面的前五个字段都是由JWT的标准所定义的。

  • iss:该JWT的签发者。
  • sub:该JWT所面向的用户。
  • aud:接收该JWT的一方。
  • exp(expires):什么时候过期,这里是一个UNIX时间戳。
  • iat(issued at):在什么时候签发的。

将上面的JSON对象进行Base64编码后可以得到一串字符串。这个字符串我们将它称作JWTPayload (载荷)。

1.5.3 签名( Signature )

将上面的两个编码后的字符串都用符号 . 连接在一起 (头部在前),就形成了一串新的字符串。最后,我们将上面拼接完的字符串用HS256算法进行加密。在加密的时候,我们还需要提供一个密钥(secret)。通过密钥和加密算法加密后的部分就叫作签名。

总结 JWT 生成过程为:

  1. 头部JSON对象 --> Base64 --> JWT的头部Head
  2. 荷载JSON对象 --> Base64 --> JWT的荷载Payload
  3. JWTHead.JWTPayload --> HS256加密 --> JWT的签名Signature
  4. JWT的完整格式:Head.Payload.Signature

下面通过一个实例了解JWT机制实现认证的过程。当用户第一次登录系统时,如图4.17所示。

创建JWT的步骤如下。

(1)第一次登录,用户从客户端输人用户名/密码,提交后到服务器的登录处理Action层 ( Login Action)。

Login Action.png

第4章 接口测试的基础 2.png

1598504-20190202220449263-1608141775.png

2 HTTP 协议

网络协议就是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。

为了使不同计算机厂家 生产的计算机能够相互通信,以便在更大的范围内建立计算机网络,国际标准化组织(ISO)在1978 年提出了“开放系统互联参考模型”,即著名的 OSIRM 模型(Open System Itereonnection/RefrerceModel)。它将计算机网络体系结构的通信协议划分为七层,自下而上依次为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

每一层都有其不同的含义及网络协议。

网络结构层 协议
物理层 以太网、调制解调器、电力线通信(PLC)、SONET/SDH、光导纤维、同轴电缆、双绞线等。
数据链路层 Wi-Fi(EEE 82.11)、WiMAX(IEEE 802.16)、ATM、令牌环、PPP、L2TP、PPTP等。
网络层协议 IP(IPv4、IPv6)、ICMP、ICMPv6、IGMP、IS-IS、IPsec、 ARP、RARP等。
传输层协议 TCP、UDP、TLS、 DCCP、SCTP、 RSVP、 OSPF 等。
应用层协议 DNS、FTP、Gopher、HTTP、IMAP4、POP3、SIP、SSH、TELNET、RPC、SDP、SOAP、GTP等。

本节主要讲的就是应用层中被应用最多的协议:HTTP 协议。

2.1 HTTP 协议介绍

HTTP/1.0 没有充分考虑分层代理、缓存以及持久连接和虚拟主机的需求的影响。并且随着不完善的 HTTP/1.0 应用程序的激增,迫切需要一个新的版本,以便使两个通信程序能够确定彼此真实的能力。此规范协议叫做HTTP/1.1,这个协议与HTTP/1.0相比,更为严格,以确保各个协议的特征得到可靠实现。

把HTTP协议的官方定义进行归纳,得出HTTP协议的4个关键点。

(1)HTTP 是建立在 TCP/IP 协议之上,面向应用层的超文本传输协议。

(2)它由请求和响应组成,完全符合标准的客户端服务器的请求响应模型。

(3)协议很轻便简单,并且请求与请求间没有关联,是无状态性的协议。

(4)为了弥补这种无状态性就需要使用 HTTP 协议的扩展 Cookie 等方式建立关联。

(5)HTTP 协议工作于客户端-服务器的架构上,采用请求/响应模型。

2.2 Uniform Resource Locator(URL)

  • URL:统一资源定位器/统一资源定位系统。HTTP/1.0支持:GET、POST、HEAD三种HTTP请求方法。
  • URI:统一资源定位标识符(Uniform Resource Identifiers),URL 是一种特殊类型的 URI,包含了用于查找某个资源的足够的信息。HTTP/1.1是当前正在使用的版本。该版本默认采用持久连接,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。HTTP/1.1 新增了:OPTIONS、PUT、DELETE、TRACE、CONNECT 五种 HTTP 请求方法。

URL 的基本格式如下:

1
2
schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]
<方案>://<用户名>:<密码>@主机:端口/路径;参数?查询#片段

URL主要有三个作用。

(1)HTTP 是 URL 的方案,方案告诉客户端使用什么样的协议去访问服务器。

(2)Host: www.example.com, 指服务器的位置。

(3)/index.html是资源路径,说明了请求的是服务器上哪个特定的本地资源。

我们以链接http://www.kath2.com/news/index.asp?ID=210&page=1#name 为例,对 URL 进行详解。

URL 一般分为以下几个部分。

  1. 协议部分:该 URL 的协议部分为HTTP:,这代表网页使用的是 HTTP 协议。在 Internet 中可以使用多种协议,如HTTPS、Ftp 等。在HTTP后面的//为分隔符。
  2. 域名部分:该 URL 的域名部分为www.kath2.com 。一个 URL 中,也可以使用 IP 地址作为域名使用。
  3. 端口部分:跟在域名后面的是端口,域名和端口之间使用 . 作为分隔符。端口不是一 个 URL 必需的部分,如果省略端口部分,将采用默认端口。例如,HTTP 的默认端口为80, HTTPS 的默认端口为443
  4. 虚拟目录部分:从域名后的第一个/开始到最后一个/为止,是虛拟目录部分。 虚拟目录也不是一个 URL必需的部分。本例中的虚拟目录是/news/
  5. 文件名部分:从域名后的最后一个/开始到?为止,是文件名部分。
    1. 如果没有?,则是从域名后的最后一个/开始到#为止,是文件名部分。
    2. 如果没有?#,那么从域名后的最后一个/开始到结束,都是文件名部分。 本例中的文件名是index.asp 。文件名部分也不是一个 URL 必需的部分,如果省略该部分,则使用默认的文件名。
  6. 锚部分:从#开始到最后,都是锚部分。本例中的锚部分是name 。锚部分也不是一个 URL 必需的部分。
  7. 参数部分:从?开始到# 为止之间的部分为参数部分,又称搜索部分、查询部分。 本例中的参数部分为ID= -210&page=1。可以允许有多个参数,参数与参数之间用&作为分隔符。

2.3 请求报文(request)

2.3.1 报文格式

屏幕快照 2020-11-06 下午2.37.26.png

request 报文的结构分为 4 部分:

  • 请求行(request line)
  • 请求头部(header)
  • 空行
  • 主体(body)

header 和 body 之间有个空行

1820506-20190928150409842-1112819644 (1).png

2.3.2 请求行

一、请求方法

请求行中包括请求方法(GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT),其中最常用的为GET、POST

请求的起始行以方法作为开始,方法用来告诉服务器要如何做。

在开发中通常有两种请求方式。

请求方式 描述
GET 是以实体的方式得到由请求URI所指定资源的信息,如果请求 URI 只是一个数据产生过程,那么最终要在响应实体中返回的是处理过程的结果所指向的资源,而不是处理过程的描述。
POST 用来向目的服务器发出请求,要求它接收被附在请求后的实体,并把它当作请求队列中请求 URI 所指定资源的附加新子项,所以 post 请求可能会导致新的资源的建立和/或已有资源的修改。
HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或调试。

二、HTTP版本

协议版本 描述
HTTP/1.0 HTTP/1.0支持:GET、POST、HEAD三种HTTP请求方法。
HTTP/1.1 HTTP/1.1是当前正在使用的版本。该版本默认采用持久连接,并能很好地配合代理服务器工作。还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。HTTP/1.1新增了:OPTIONS、PUT、DELETE、TRACE、CONNECT 五种 HTTP 请求方法。

 

2.3.3 请求头

请求报头域主要用于指定被请求资源的 Internet 主机和端口号,它通常从 HTTP URL 中提取出来。

请求报文的 header 属性为以下六个部分:

  • Cache
  • Client
  • Cookies
  • Miscellaneou
  • Security
  • Transport

一、Cache 头域

Cache 字段名称 字段值说明
Cache-Control 用来指定Response-Request遵循的缓存机制。各个指令含义如下。
Cache-Control:Public:可以被任何缓存所缓存。
Cache-Control:Private:指示响应信息的全部或部分用于单个用户,而不能用一个共享缓存来缓存。这可以让源服务器指示,响应的特定部分只用于一个用户,而对其他用户的请求则是一个不可靠的响应。
Cache-Control:no-cache:所有内容都不会被缓存,请求头里的no-cache表示浏览器不想读 缓存,并不是说没有缓存。一般在浏览器按Ctrl+F5键强制刷新时,请求头里也会有这个no-cache,也就是跳过强缓存和协商缓存阶段,直接请求服务器。
Cache-Control:max-age=0:指示客户端愿意接收其绝对时间不大于指定的时间,以秒计。 如果直接按F5键的话,请求头是max-age =0,只跳过强缓存,但进行协商缓存。
if-Modified-Since 把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果时间一致,那么返回304,客户端就直接使用本地缓存文件。如果时间不一致,就会返回200和新的文件内容。客户端接到之后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。
本地文件的修改时间和服务器上的文件修改时间一致, 说明文件没有被更新。HTTP服务器返回304,告诉客户端使用本地缓存文件。
If-None-Match If-None-MatchETag一起工作,工作原理是在HTTP response 中添加 ETag 信息。当用户再 次请求该资源时,将在 HTTP request 中加入If-None-Match信息( ETag的值)。如果服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件,否则将返回200状态和新的资源和Etag。 使用这样的机制将提高网站的性能。
If-None-MachETag的值一致, 说明文件没有被更新。服务器将返回304,告诉客户端使用本地缓存文件。
Pragma 防止页面被缓存,HTTP/L.1版本中, 它和Cache-Coltrol:no-cache的作用一模一样。 Pargma只有一个用法,例如,Pragma: no-cache

二、Client头域

Client字段名称 字段值说明
Accept 浏览器端可以接收的媒体类型。
Accept: text/html 代表浏览器可以接收服务器发回的类型为text/html也就是我们常说的HTML文档,如果服务器无法返回text/html类型的数据,服务器应该返回一个406错误(non acceptable)
Accept:*/* 通配符*代表任意类型。代表浏览器可以处理所有类型。
Accept -Encoding 浏览器声明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法 ( gzipdeflate) 。例如,Accept-Encoding: gzip, deflate
Accept - Language 浏览器声明自己接收的语言。语言跟字符集的区别是:中文是语言,中文有多种字符集,比 如bigsgb2312gbk等。
User-Agent 告诉 HTTP 服务器客户端使用的操作系统和浏览器的名称和版本。我们上网登录论坛的时候,往往会看到一些欢迎信息,其中列出了你的操作系统的名称和版本、你所使用的浏览器的名称和版本,实际上,服务器应用程序就是从User-Agent这个请求报头域中获取到这些信息的。
Accept-Charset 浏览器声明自己接收的字符集,如gb2312utf-8等。

三、Cookie

Cookie字段名称 字段值说明
Cookie 最重要的 header,将Cookie 的值发送给 HTTP 服务器。

四、Miscellaneous 头域

Miscellaneous字段名称 字段值说明
Referer 提供了 request 的上下文信息的服务器,告诉服务器我是从哪个链接过来的。有些统计数据需要用到此头域。比如从我的主页上链接到统计服务器那里,该服务器就能够从HTTP Referer中统计出每天有多少用户点击我主页上的链接访问他的网站。

五、Entity 头域

Entity字段名称 字段值描述
Content-Length 发送给 HTTP 服务器数据的长度。
Content-Type ①表示具体请求中的媒体类型信息。常见的媒体格式类型如下。
text/html:HTML格式
text/plain:纯文本格式
text/xml:XML格式
imag/gif:gif图片格式
image/jpeg:jpg图片格式
image/png:png图片格式
②以application开头的媒体格式类型如下:
application/xhtml+xml:XHTML格式
application/xml:XML数据格式
application/atom+xml:Atom XML聚合格式
application/json:JSON数据格式
application/pdf:pdf格式
application/msword:Word文档格式
application/octet-stream:二进制流数据
application/x-www-form-urlencoded<form encType="">中默认的encTypeform表单数据被编码为key/value
格式发送到服务器(表单默认的提交数据的格式)。
③另外一种常见的媒体格式是上传文件之时使用的。
multipart/form-data:需要在表单中进行文件上传时,就需要使用该格式。

六、Transport 头域

Transport字段名称 字段值描述
Connection Connection: keep-alive:当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建 立的连接。
Connection: close:代表一个 request 完成后,客户端和服务器之间用于传输 HTTP 数据的TCP 连接会关闭,当客户端再次发送 request 时,需要重新建立 TCP 连接。
Host 发送请求时,该报头域是必需的

参考文章:

2.4 响应报文(response)

2.4.1 报文格式

Response 报文的结构也分为 4 部分:

  • 响应状态(response code)
  • 响应头(response header)
  • 空行
  • 响应主体(response body)

header 和 body 之间也有一个空行。

屏幕快照 2020-11-06 下午2.40.03.png

2.4.2 状态行

状态行最重要的一部分就是响应报文的状态码

当客户端发起一次 HTTP请求后,服务器会返回一个包含 HTTP 状态码的信息头(server header )用以响应客户端的请求。response 消息中的第一行叫作状态行,由 HTTP 协议版本号状态码状态消息三部分组成。

状态码用来告诉 HTTP 客户端 HTTP 服务器是否产生了预期的 response。

状态码总共只有三位第一位表示状态类别,共分为五种

  • 1xx:是进度通知类状态,意思就是说“请求我已经收到了,或你的请求我正在处理”。
  • 2xx:表示“你的请求我已经成功处理了”。
  • 3xx:即重定向,也就是服务器告诉客户端“你要的资源搬家了,你到某某地方再去找它吧”。
  • 4xx:客户端发来的响应报文里有些错误,比如语法错误或请求的资源不存在等。
  • 5xx:服务器端有些问题,已经无法处理完成你的请求了。

常用的一些状态码如下:

  • 200 OK:客户端,你的请求处理成功,你要的东西就在响应报文里了。
  • 301 Moved Permanently:客户端,你要请求的资源已经永久地搬家了,我把它的新地址放到了Location头部域中了。
  • 302 Moved Temporarily:客户端,你要请求的源临时有事去别的地方了,我把它的位置放到Location头部域中了,你可以先去那里找它.不过它应该会回到它原来的家的。
  • 304 Not Modified:客户端,你要请求的资源自从上次你请求之后,就再也没有改动过。我想你应该早就有这个资源了。所以在响应报文的数据部分我就没有再放这个资源。
  • 400 Bad Request客户端,你发来的请求报文里有语法情误,服务器端实在看不懂。
  • 401 Unauthorized:客户端,你发来的请求不是合法来源的请求,你是没有被授权的客户端吧。
  • 403 Forbidden:服务器端顺利收到了客户端的请求,但因为某些理由,服务器端拒绝为你提供服务。
  • 404 Not Found:客户端,你请求的资源不存在,八成是资源地址写错了。
  • 500 Internal Server Error:很遗憾,服务器不能给你提供服务了,服务器内部出现了不可预知的问题。
  • 502 Bad Gateway:客户端你好,我是请求报文的代理服务器,持有资源的那个服务器在给我发送资源时出问题了。
  • 503 Server Unavailable:服务器现在可能是太忙了,暂时不能给你这个客户端提供服务,或许稍后会恢复的。

除了以上几个常用的状态码,还有许多其他含义的状态码。完整状态码含义表如下。

(1)请求收到,继续处理

状态码 状态描述 状态说明
100 Continue 客户端必须继续发出请求
101 Switching Protocols 客户端要求服务器根据请求转换 HTTP 协议版本

(2)成功响应,操作成功收到,分析、接受

状态码 状态描述 状态说明
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源。提示知道新文件的URL
202 Accepted 已接受和处理,但处理未完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
返回信息不确定或不完整
204 No Content 无内容。服务器成功处理,但未返回内容。但返回信息为空
在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)必须复位当前已经测览过的文件
206 Partial Content 部分内容。服务器成功处理了部分 GET 请求

(3)重定向,完成此请求必须进一步处理

状态码 状态描述 状态说明
300 Multiple Choices 多种选择。请求的资源可在多处得到
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新 URI ,返回信息会包括新的 URI ,浏览器会自动定向到新 URI。
今后任何新的请求都应使用新的 URI 代替
302 Found 临时移动。与 301 类似。但资源只是临时被移动。客户端应继续使用原有 URI
只有在Cache-ControlExpires中进行了指定的情况下,这个响应才是可缓存的
303 See Other 查看其它地址。对应当前请求的响应可以在另一个 URI 上被找到,使用 GET 和 POST 请求查看
这个方法的存在主要是为了允许由脚本激活的 POST 请求输出重定向到一个新的资源
304 Not Modified 未修改。GET 所请求的资源未修改,服务器返回此状态码时,不会返回任何资源
304 响应禁止包含消息体,因此始终以消息头后的第一个空行结尾
305 Use Proxy 使用代理。所请求的资源必须通过服务器指定的代理访问
306 Unused 已经被废弃的HTTP状态码,前一版本 HTTP 中使用用的代码,现行版本中 HTTP 不再使用
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向。

(4)请求错误,请求包含一个错误语法或不能完成

状态码 状态描述 状态说明
400 Bad Request 错误请求,如语法错误
401 Unauthorized 未授权,请求要求用户的身份认证
401.1 未授权:登录失败
401.2 未授权:服务器配置问题导致登录失败
401.3 未授权:禁止访问资源,由于 ACL 对资源的限制而未获得授权。
401.4 授权被筛选器拒绝
401.5 未授权:ISAPI 或 CGl 授权失败
401.7 访问被 Web 服务器上的 URL 授权策略拒绝。这个错误代码为 IIS 6.0 所专用。
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
403.1 禁止可执行访问
403.2 禁止读访问
403.3 禁止写访问
403.4 禁止访问:要求SSL
403.5 禁止访问:要求SSL128
403.6 禁止访问:IP地址被拒绝
403.7 禁止访问:要求客户证书
403.8 禁止访问:禁止站点访问
403.9 禁止访问:连接的用户过多
403.10 禁止访问:配置无效
403.11 禁止访问:密码更改
403.12 禁止访问:映射器拒绝访问
403.13 禁止访问:客户证书已被吊销
403.14 禁止访问:Web 服务器被配置不列出此目录的内容
403.15 禁止访问:客户访问许可过多
403.16 禁止访问:客户证书不可信或者无效
403.17 禁止访问:客户证书已经到期或者尚未生效
403.18 客户端证书已过期或尚未生效。
403.19 不能为这个应用程序池中的客户端执行 CGI。这个错误代码为 IIS 6.0 所专用。
403.20 Passport 登录失败。这个错误代码为 IIS 6.0 所专用。
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。没有发现文件、 查询或URI
405 Method Not Allowed 客户端请求中的方法被禁止。用户在Request-Line字段定义的方法不允许
406 Not Acceptable 无法接受用户发送的请求,请求资源不可被访问
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 客户端没有在用户指定的时间内完成请求,超时
409 Conflict 由于和被请求的资源的当前状态之间存在冲突,请求无法完成。
410 Gone 客户端请求的资源已经不存在。
410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 一个或多个请求头字段在当前请求中错误
413 Request Entity Too Large 请求的资源大于服务器允许的大小,服务器无法处理,因此拒绝请求。
414 Request-URI Too Large 请求的 URI 过长( URI 通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式,请求资源不支持请求项目格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足 Expect 的请求头信息

(5)服务端响应

状态码 状态描述 状态说明
500 Internal Server Error 服务器内部错误,无法完成请求
500.11 服务器关闭
500.12 应用程序重新启动
500.13 服务器太忙
500.14 应用程序无效
500.15 不允许请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 网关错误。
作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。
延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理
2.4.3 响应头

一、Cache 头域

Cache字段名称 字段值说明
Cache-Concrol 缓存内容,上一节已说明。
Date 生成消息的具体时间和日期。
Expires 浏览器会制定过期时间内使用本地缓存。格林尼治时间 GMT。
Pragma 浏览内容不会被缓存

二、Cookie/Login 头域

Cookie字段名称 字段值说明
P3P 用于跨域设置 Cookie,这样可以解决iframe跨域访问 Cookie 的问题。
Set-Cookie 用于把 Cookie 发送到客户端浏览器,每一个写入 Cookie 都会生成个Set-Cookie

三、Entity 头域

Entity字段名称 字段值说明
ETag If-None-Match配合使用。
Last-Modified 用于指示资源的最后修改日期和时间。
Content-Type Web服务器告诉浏览器自己响应的对象的类型和字符集。
Content-Length 指明实体正文的长度,以字节方式存储的十进制数字来表示。
Content-Encoding Web服务器表明自己使用了什么压缩方法( gzip, deflate )压缩响应中的对象。
Content-Language Web服务器告诉浏览器自己响应的对象的语言。

四、Miscellaneous 头域

Miscellaneous字段名称 字段值说明
Server 指明 HTTP 服务器的软件信息。
X-AspNet-Version 如果网站是用ASP.NET开发的,这个header用来表示ASP.NET的版本。
X-Powered-By 表示网站是用什么技术开发的。

五、Transport 头域

Transport字段名称 字段值说明
Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭
如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接
Connection: close 代表一个 request 完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接会关闭
当客户端再次发送 Request 时,需要重新建立 TCP 连接。

一个传输层的实际环流,它是建立在两个相互通信的应用程序之间。

在 HTTP1.1,中,requestresponse头中都有可能出现个Connection的头,此header的含义是当 Client 和 Server 通信时对于长连接如何进行处理。

  • HTTP/1.0,Connection: close
  • HTTP/1.1,Connection: keep-alive
  • HTTP TCP,无状态,面向连接。
  • HTTP UDP,无状态,无连接

HTTP 的无状态和Connection: keep-alive是两个不同的概念。无状态是指协议对于事务处理没有记忆,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和之前打开这个服务器上的网页之间没有任何联系,所以出现了 Cookie、Session等来解决无状态的问题。

keep-alive 不会永久保持,它有一个保持时间。

六、Location 头域

用于重定向一个新的位置,包含新的 URL 地址。

七、Security 头域

Strict-Transport-Security: max-age-31536000

网站通过 HTTP Strict Transport Security (HSTS ) 通知浏览器,这个网站禁止使用 HTTP 方式加载,浏览器应该自动把所有尝试使用 HTTP 的请求自动替换为 HTTPS 请求。

当你的网站第一次发送 HTTPS 请求,服务器响应Strict-Transport-Security头,浏览器记录下这些信息。然后后面尝试访问这个网站的请求都会自动把 HTTP 替换为 HTTPS 。当 HTTPS 头设置的过期时间到了,后面通过HTTP 的访问恢复到正常模式,不会再自动跳转到 HTTPS。每次浏览器接收到Strict-Transport-Security头,它都会更新这个网站的过期时间,所以网站可以刷新这些信息,防止过期发生。

会话保持、长连接、短链接:

关于同源策略: