http通信协议的基本原理
- 在远程通信场景中http协议是一种应用广泛的应用层协议
http请求的通信流程
DNS服务
- Domain Name System
- DNS服务是和HTTP协议一样位于应用层的协议
- 提供 域名、IP 之间的解析服务
http通信协议的组成
- http是基于应用层的协议
- 在传输层使用了TCP通信协议进行传输
协议的定义
- 协议是 两个或多个需要进行网络通信的程序 达成的一种约定
URI 和 URL
-
http请求通过URI定位资源
-
URL (Uniform Resource Locator)— 统一资源定位符,用于描述一个网络上的资源
-
URI 用字符串标识某一互联网资源
-
URL 则表示资源的地点(在互联网中所处的位置)
-
URL 是 URI 的子集
http://www.xxx.com:80/java/index.html?name=mic#head
schema://host[:port#]/path/.../?[url-params]#[query-string]
schema 指定应用层使用的协议(如 http,https, ftp等)
host http服务器的IP地址活着域名
post# http服务器端口,默认80
path 访问资源路径
query-string 查询字符串
所以,通过url地址,我们可以得到用户使用http协议访问指定服务器上对应进程的资源,并且携带的请求参数。
MIME Type
- 服务器通过用户请求返回资源-》浏览器对资源解析并渲染
- 针对不同类型如图片类型、视频类型、Js等
- Q:浏览器如何识别当前类型并做不同渲染?
- A:通过 MIME Type
什么是MIME Type?
- 描述消息内容类型的因特网标准
- 常见类型
- 文本文件:text/html text/plain text/css application/xhtml
- 图片文件:image/jpeg image/gif image/png
- 视频文件:video/mpeg video/quicktime
设置文件渲染类型的方式?
- Accept
- 表示客户端希望接收的数据类型。服务器根据Accept请求头产生相对应的数据。
- Content-Type
- 发送端发送的实体数据类型
response.setContentType("application/json;charset=utf-8") 表示服务端返回的数据格式是json
- 若Accept和Content-Type不一致,浏览器将无法解析
状态码的概念
- 当客户端向服务端发送请求的时候,描述服务端返回的请求处理结果
类别 | 原因短语 | |
---|---|---|
1 | Information(信息状态码) | 接收的请求正在处理 |
2 | Success(成功状态码) | 请求正常处理完毕 |
3 | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4 | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5 | Server Error(服务端错误状态码) | 服务器无法处理请求 |
不同请求的操作方式
- GET
- 客户端发送一个URI地址去获取服务端资源(一般用于查询),传输数据有限制
- POST
- 传输实体给到服务端,让服务端去保存(一般用于创建操作)
- PUT
- 向服务器发送数据,一般用于更新数据操作
- DELETE
- 一般用于删除操作
- HEAD :获得报文头部
- OPTIONS : 询问支持的方法
- TRACE :追踪路径
- CONNECT : 用隧道协议连接代理
REST架构风格
- 严格规定对于不同类型设置合适的请求方法
- Q:为什么要用REST架构?
- 服务化架构普及,http协议使用频率越来越高
- 有状态和无状态请求混用
- 更好地利用http协议提供的规则
- REST面向资源,每一个URI代表一个资源
- 强调无状态化,服务端不能存储来自某个客户请求中的信息
- 强调URL暴露资源时,不要再URI中出现动词
- 合理使用http状态码、请求方法
http协议的完整组成
- 请求报文
- 响应报文
请求报文
- 请求行、请求头部、请求数据
请求行
- 由方法字段、URL字段和http协议版本字段3个字段组成,使用空格分离
- ex:GET /data/index.jsp HTTP/1.1
- 方法字段就是HTTP使用的请求方法,比如常见的GET/POST
- 协议版本字段有两种:HTTP1.0/HTTP1.1
- HTTP1.0 每个连接传送一个请求或响应,请求就会关闭,没有host字段
- HTTP1.1 在同一个连接中可以传送多个请求和响应,可重叠和同时进行,必须有host字段
请求头部
- 客户端向服务器发送请求的时候必须指明请求类型,如有必要,还可以选择发送其它的请求头。大多数请求头并非必须,但Content-Length除外
- 常见的请求头有 Accept、Accept-Charset、Accept-Encoding、Content-Length、Host 等
请求数据
- 需要提交的数据
响应报文
- 响应行、响应头、响应体
- 响应行:协议版本、状态码、状态的原因短语
http协议中的扩展
-
传输文件过大的解决办法?
- 对文件进行压缩,减少文件大小
- 分割传输:在传输大容量数据时,把数据分割多块,让浏览器逐步显示页面
- 这种把实体主体分块的功能成为分块传输编码(Chunked Transfer Coding)
-
持久化连接
- HTTP/1.1中支持了持久化连接—只要一次连接建立之后,只要客户端和服务端没有明确提出断开连接,tcp连接就会一直保持连接状态
- 通过HTTP1.1中有一个Transport段,携带Connection:Keep-Alive,表示希望此条连接作为持久连接。
- 持久化连接默认激活,可在报文中显示地添加Connection:close首部表示事务结束之后要将连接关闭
-
管道化连接
- 不用等待响应亦可直接发送下一个请求。能够实现同时并行发送多个请求
http协议的特点
- Http无状态协议
- HTTP协议本身不会对请求和响应本身之间的通信状态做保存
- 如何实现有状态的协议
- 客户端支持的cookie — Http协议中引入 cookie 技术,用来解决http协议无状态的问题
- 通过在请求和响应报文中写入Cookie信息来控制客户端状态
- Cookie根据服务器的响应报文 Set-Cookie 的首部字段信息,通知客户端保存Cookie
- 当客户端再次向服务器发送请求时,会自动在请求报文中假如Cookie值后发送出去
- 服务端支持的session—使用session机制来保存服务端的对象状态
- 当程序需要为某个客户端创建一个session
- 服务器首先检查客户端请求是否包含了一个session标识 — session id
- 如果已有 session id — 说明已经为客户端创建过 session
- 服务端按照session id把这个session检索出来使用
- 如果没有 session id,则为此客户端创建一个session,并生成相关联的 session id
Http协议安全传输
- http协议通信过程中,是基于明文通信的,底层基于TCP/IP协议进行通信
- 按照TCP/IP协议族的工作机制,通信内容可能遭到拦截和窃取
安全传输协议
- 由于HTTP协议通信的不安全性
- https — 对传输通道进行加密的方式
- https:一种加密的超文本传输协议
- 传输过程中对数据做了完全加密
- https同http协议一样处于TCP传输层之上
- 在TCP协议层之上增加了一层SSL(Secure Socket Layer,安全层)或者 TLS(Transport Layer Security) 安全层传输协议组合使用用于构造加密通道
HTTPS实现加密传输机制
- 公钥、私钥和数字证书
HTTPS证书申请
- 服务器上生成CSR文件
- 证书申请文件:证书公钥、Hash签名算法、申请的域名、公司名称、职位等信息
- CSR文件和其它所需证件上传到CA认证机构
- CA机构收到认证申请,使用申请中的hash算法,对部分内容进行摘要
- CA机构使用自己的私钥,对摘要信息进行签名(相当于证书的唯一编号)
- CA机构把签名过的证书通过邮件的形式发送到申请者手中
- 申请者收到证书之后部署到自己的web服务器中
HTTPS通信过程
- 客户端发起请求
- 三次握手—TCP连接建立—生成随机数client.random:用于生成对话密钥
- 生成sessionid用于保持同一会话
- 服务端收到请求,然后响应
- 确认加密通道版本—服务端生成随机数server.random:用于生成对话密钥
- 确认使用的加密算法:用于后续的握手消息进行签名防止篡改
- 服务器证书—CA机构颁发的证书
- 客户端对收到的证书进行验证
- 证书是否是上级CA签发—是否过期—是否被吊销
- 验证签名:私钥签名、公钥验签
- CA机构在签发证书的时候,会使用自己的私钥对证书进行签名
- 使用对应的算法字段对证书进行摘要,然后使用RSA算法对摘要进行私钥签名
- 私钥签名后只有公钥才能进行验签
- 浏览器使用内置在操作系统上的CA机构的公钥对服务器的证书进行验签
- 验签之后CA机构使用sha256(算法字段)进行证书摘要
- 客户端再次使用sha256对证书内容进行一次摘要—对比得到的值
- 验证通过之后—客户端生成随机数pre-master secret
- 客户端根据之前的Client.random + sever.random + pre-master 对称密钥
- 使用证书中的公钥进行加密
- 利用协商好的hash算法,对握手消息取hash值
- (取hash值,把握手消息做一个签名,验证消息是否被篡改过)
- 最后随机数加密**“握手消息+握手消息 HASH 值(签名)”** 发送给服务端
- 服务端接收到随机数
- 用私钥对密文进行解密
- 得到client.random/server.random/pre-master secret, HASH 值
- 与传递过来的hash值进行对比
- 随机密码加密一段握手消息(握手消息+握手消息的 HASH 值)给客户端
- 客户端接收消息
- 用随机数解密并计算握手消息的HASH值,与服务端传递过来的HASH值一致,握手过程结束
- 之后通信过程根据交互过程中生成
- pre master secret /client.random/server.random 通过算法得出 session Key
- 作为后续交互过程中的对称密钥