熟悉 HTTP 协议结构和通讯原理
1. HTTP 协议特点
1.1 支持客户/服务器模式
客户/服务器模式工作的方式是由客户端向服务器发出请求,服务器端响应请求,并进行相应任务。
HTTP 规则规定了请求从客户端发出,然后服务端发出响应,因此是客户端先发出请求。
1.2 简单快速
- 客户向服务器请求服务时,只需传送请求方法和路径。
- 请求方法常用的有 GET、POST。每种方法规定了客户与服务器联系的类型不同
- 由于 HTTP 协议简单,使得 HTTP 服务器的规模程序规模小,因而通信速度很快。
1.3 灵活
- HTTP 允许传输任意类型的数据对象
- 正在传输的类型由 Content-Type (Content-Type 是 HTTP 包中用来表示内容类型的标识) 加以标记。
1.4 无连接
-
无连接的含义是限制每次连接只处理一个请求。
-
服务器处理完客户的请求,并收到客户的应答后,即断开连接。
-
采用这种方式可以节省传输时间。
TCP 长连接:随着时间的推移,网页变得越来越复杂,每次 HTTP 请求都建立一次 TCP 连接显得效率低下,因此提出了 keep-alive 功能,让客户端对服务器的 TCP 连接持续有效,避免重新建立连接。keep-alive 设置超时时间,避免连接一直没断开。
1.5 无状态
- HTTP 协议是无状态协议
- 无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
- 另一方面,在服务器不需要先前信息时它的应答就比较快。
Web 应用程序出现后,无状态的特性阻碍了交互,因此产生了 cookie 和 session。
2. URL 与 URI 的区别与联系
Q:我们输入在浏览器里的 Web 地址应该叫 URL 还是 URI?
定义
- URI:统一资源标识符(Uniform Resource Identifier,URI),是一个紧凑的字符串用来表示抽象或物理资源。
- URI 可以进一步被分为定位符、名字或者两者都是。
- URL(统一资源定位符,Uniform Resource Locator)是 URI 的子集,除了确定一个资源,还提供一种定位该资源的主要访问机制(如其网络”位置“)。
区别
- URI 可以分为 URL,URN 或同时具备 locators 和 names 特性的一个东西。
- URN 作用就好像一个人的名字,URL 就像一个人的地址。
- 换句话说,URN 确定了东西的身份,URL 提供了找到它的方式。
总结
- URL 是 URI 的一种,但不是所有的 URI 都是 URL
- URI 和 URL 最大的区别是 ”访问机制“,即协议。因此输入 web 地址是 URI,因为并不清楚是 https 协议还是 ftp 协议,只是一个身份标识。
- URN 是唯一标识的一部分,是身份信息
3. HTTP 报文结构解析
3.1 请求报文
请求报文由三部分组成,请求行,请求头和请求体。
请求报文行
请求方法,GET 和 POST 是最常见的 HTTP 方法,除此以外还包括 DELETE、HEAD、OPTIONS、PUT、TRACE。
请求对应的 URI 地址,它和报文头的 Host 属性组成完整的请求 URI。
协议名称及版本号。
请求报文头
报文头包含若干个属性,格式为“属性名: 属性值”,服务端据此获取客户端的信息。
与缓存相关的规则信息,均包含在 header 中
请求报文体
报文体将一个页面表单中的组件值通过param1=value1¶m2=value2 的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于 “/chapter15/user.html? param1=value1¶m2=value2” 的方式传递请求参数。
3.2 HTTP 报文头
-
HTTP 的报文头大体可以分为四类,分别是:
通用报文头、请求报文头、响应报文头和实体报文头。
-
在 HTTP/1.1 里一共规范了 47 种报文头字段。
通用报文头
-
Connection
Connection: keep-alive
当一个网页打开完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接 。
Connection: close
代表一个 Request 完成后,客户端和服务器之间用于传输 HTTP 数据的 TCP 连接会关闭,当客户端再次发送 Request,需要重新建立 TCP 连接。
请求报文头
-
Accept
作用:浏览器端可以接受的媒体类型
text/html 代表服务器可以接收服务器回发的类型为 text/html 也就是我们常说的 html 文档,如果服务器无法返回 text/html 类型的数据,服务器应该返回一个 406 错误(Non Acceptable)
Accept: */* 代表浏览器可以处理所有类型
如果想要给显示的媒体类型增加优先级,则使用 q= 来额外表示权重值;权重值 q 的范围是 0 - 1 (可精确到小数点后 3 位),且 1 为最大值。不指定权重 q 值时,默认权重为 q = 1.0。当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。
-
Accept-Encoding
作用:浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)
Accept-Encoding: gzip, deflate
-
Accept-Language
作用:浏览器申明自己接收的语言
Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
客户端在服务器有中文版资源的情况下,会请求其返回中文版对应的响应,没有中文版时,则请求返回英文版响应。
-
Host
作用:请求报头域主要用于指定被请求资源的 Internet 主机和端口号,它通常从 HTTP URL 中提取出来
-
Referer
当浏览器向 web 服务器发送请求的时候,一般会带上 Referer,告诉服务器我是从哪个页面链接过来的,服务器借此可以获得一些信息用于处理
-
User-Agent
作用:告诉 HTTP 服务器,客户端使用的操作系统和浏览器的名称和版本。
很多情况下我们会通过 User-Agent 来判断浏览器类型,从而进行不同的兼容设计。
响应报文头
实体报文头
-
Content-Type
作用:说明了报文体内对象的媒体类型
3.3 响应报文
响应报文由三部分组成,响应行,响应头和响应体。
响应行
包含报文协议及版本,以及状态码和状态描述
响应头
响应报文头,也是由多个属性组成
响应体
响应报文体,即我们真正要的”干货“。
4. HTTP 请求方法剖析
4.1 GET
get 方法可以从 url 里边获取到信息,并且 url 长度有限制,因此无法携带大量信息。
4.2 POST
4.3 PUT
幂等性:一个操作无论执行多少次,都会得到相同的结果。
创建对象用 post,更新对象用 put
4.4 HEAD/DELETE
4.5 OPTIONS
4.6 TRACE/CONNECT
6. HTTP 响应状态码拆解
6. HTTP 状态管理:Cookie 与 Session
6.1 Cookie
-
Cookie 实际上是一小段文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就向客户端浏览器颁发一个 Cookie。
-
客户端浏览器会把 Cookie 保存起来。当浏览器再请求该网站的时候,浏览器把请求的网址连同该 Cookie 一同提交给服务器。服务器检查该 Cookie,以此来辨认用户状态。
6.2 Session
- Session 是另一种记录客户状态的机制,保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。
- 客户端浏览器再次访问时只需要从该 Session 中查找该用户的状态就可以了。
保存 Session ID 的方式
-
Cookie
-
URL 重写,附加参数或者查询字符串
-
隐藏表单,服务器自动修改表单,添加一个隐藏字段,表单提交的时候可以把 session 传递到服务端。
Session 的有效期
- Session 超时失效
- 程序调用 HttpSession.invalidate()
- 服务器进程被停止
6.3 Cookie 与 Session
- 存放位置不同。Cookie 在客户端,Session 在服务端
- 安全性(隐私策略)的不同。敏感的信息别放 Cookie 里。
- Cookie 可以保存很长时间,服务端会定时清除 Session 来缓解服务端压力。SessionID 的过期时间默认为 -1,即关闭浏览器,会话结束就清除。
- 对服务器压力的不同。Session 对服务器的压力较大。