HTTP
-
Cookie
- HTTP本身为无状态协议,即HTTP不会记录曾经传输过哪些内容
- 如果用户登录了一个网站,当他跳转到该网站其他页面后,HTTP本身并不能识别他已经登陆过
- 此时我们需要通过Cookie协议在客户端记录登录信息
- 如果让服务器记录则负担太大
- 服务器会在返回报文中加入SET-COOKIE的首部字段,客户端可以保存并在后面的通信中自动发出
-
HTTP方法
- GET
- 向服务器获取资源
- POST
- 向服务器传输数据
- 非幂等,两次相同的POST请求会在服务器创建两份资源,并返回不同的URI
- PUT
- 也是向服务器传输数据,但是不同的是他是幂等的
- 也就是如果多次发送同一数据,他会覆盖原有数据,而POST不会
- PUT可以用来更新,POST用来增加
- PUT本身没有安全机制,任何人都可以上传,所以一般网站不使用该方法
- 也是向服务器传输数据,但是不同的是他是幂等的
- HEAD
- 获得报文首部,但不返回主体部分,目的是获取通信状态
- 一般用来确认URI有效性以及资源更新日期等
- DELETE
- 向服务器删除数据
- 也和PUT一样不安全
- OPTIONS
- 查询服务器支持的HTTP方法
- 请求行:
OPTIONS * HTTP/1.1
- GET
-
多次提交问题
- 由于POST是费幂等的,因此网络有问题时,可能出现多次提交,例如发了多个重复帖子
- 解决方案一般是前端在表单中加入一个隐藏的token
- 如果多次提交,那么后端在插入数据库时会报错
-
持久连接
- 在HTTP1.0中,每一次HTTP传输都到建立断开一次TCP连接,效率低下
- 到了HTTP1.1中,默认为持久连接,即如果双方都没有提出断开,则保持连接
- 首部应该加上字段
Connection: keep-alive
- 通过
Connection: close
关闭
-
管线化
- 普通的依赖TCP协议的传输过程只有在接收到响应时才发送下一个请求
- 管线话可以同时发送多个请求
- 比如包含多个图片的网页
- 比如包含多个图片的网页
-
HTTP报文
- 请求报文由方法、HTTP版本、URI和HTTP首部组成
- 响应报文由HTTP版本、状态码和HTTP首部组成
-
报文主体(body)
- 以下消息不能含有报文主体
- HEAD 方法请求对应的响应
- 1xx、204、304 对应的响应
- CONNECT 方法对应的 2xx 响应
- 报文主体大小
- 使用
Content-Length
头部明确指明包体长度- 服务器已经知道资源大小
- 使用
Transfer-Encoding
头部指明使用 Chunk 传输方式- .服务器没法提前知道资源的大小,或者不愿意花费资源提前计算资源大小
- 每一块都使用固定的格式,前边是块的大小,后面是数据,然后最后一块大小是0
- 优点
- 基于长连接持续推送动态内容
- 压缩体积较大的包体时,不必完全压缩完(计算出头部)再发送,可以边发送边压缩
- 含
Transfer-Encoding
头部后Content-Length
头部应被忽略
- 服务器不知道资源的大小,同时也不支持chunked的传输模式,那么就既没有
content-length
头,也没有transfer-encoding
头- 这种情况下必须使用短连接,以连接结束来标示数据传输结束
- 这时候服务器返回的header里一定是
Connection:close
- 如果是keep alive,则content-length和chunk必然是二选一
- 参考:https://www.cnblogs.com/nxlhero/p/11670942.html
- 使用
- 以下消息不能含有报文主体
-
首部字段
- 报文主体可以是多种类型对象的集合
- 此时报文首部需要加上
Content-Type: multipart/form-data; boundry=XXXX
- boundry是划分标记
- 此时报文首部需要加上
- 服务器可以对同一请求返回不同的内容,比如遇到英文浏览器返回英文内容
- 此时报文首部需要加上
Accept-Encoding, Accept-Language
等字段 User-Agent
字段可以告知访问的客户端类型(手机,电脑等),服务器也可根据这一字段返回不同内容
- 此时报文首部需要加上
- 服务端先写header,再写body
- 所以header里不一定有
content-length
,如果要在header里把body大小写进去,就得提前知道body大小。如果这个body是动态生成的,服务端先生成完,再开始写header,这样需要很多额外的开销
- 所以header里不一定有
- 标注请求来源:
referer
referer
首部字段记录了该HTTP请求的来源URL,诉服务器该网页是从哪个页面链接过来的- 该字段可以被伪造
- 空
referer
字段表示该请求是直接(输入地址)访问的,不是链接跳转而来的 - 作用:
- 防盗链:只允许白名单内来源本网站的域)的请求获取资源,否则返回403
- 常用于常用于图片、视频等的防盗
- 也用于反爬虫
- 来源统计分析:例如有多少次是来自谷歌搜索结果,多少次来自百度搜索结果等
- 比如你在许多网站上投放了广告,你就可以通过referer这个首部来统计各个网站的点击情况了,进而优化广告投放方法
- 防盗链:只允许白名单内来源本网站的域)的请求获取资源,否则返回403
- 报文主体可以是多种类型对象的集合
-
POST请求格式
- form-data
- Header :
Content-Type: multipart/form-data; boundary=${bound}
- Body: 既可以上传键值对,也可以上传文件
- Header中需要boundary作为分隔符
- Header :
- x-www-form-urlencoded
- Header:
Content-Type: application/x-www-from-urlencoded
- Body: 只能上传键值对
- Header:
- raw
- Body: 可以上传text, XML, JSON,HTML等格式
- 上传JSON则 Header:
Content-Type:application/json
- form-data
-
状态码
- 状态码由三位数字和原因短语组成
- 200 OK
- 正常处理
- 204 No Content
- 成功处理,但不返回资源(资源不用更新)
- 206 Partial Content
- 返回部分资源
- 301 Moved Permanently
- 资源以及分配到新的URI了
- 304 Not Modified
- 资源找到但是不符合请求要求
- 请求报文中可能包含
If-Match, If-Modified-Since
等字段
- 400 Bad Request
- 请求报文存在语法错误
- 401 Unauthorized
- 未验证
- 第一次会请求验证,第二次视为验证失败
- 403 Forbidden
- 服务器拒绝访问
- 404 Not Found
- 未找到资源
- 500 Internal Server Error
- 服务器内部错误
- 503 Service Unavailable
- 服务器超载或停机,无法处理请求
- 200 OK
- 状态码由三位数字和原因短语组成
- 一台服务器可以通过虚拟服务器搭建多个web站点
- 通过NGINX等网关即可实现
- 此时多个域名解析后会指向同一个IP地址
- 因此需要在请求报文首部Host字段指定完整的主机名或者域名的URI
- 代理
- 可以存在于客户端或者服务端
- 优点是可以利用缓存技术减少网络流量和限制访问
- 比如客户端的代理可以禁止内网用户访问一些网站
- 缓存在传给客户端前会向源服务器确认资源的有效性
- 网管
- 客户端看来就是服务器
- 可以让外界访问非HTTP链接的服务器
- 可以设置防火墙
HTTPS
-
HTTP缺点
- 通信使用明文,会被窃听
- 不严重通信方的身份,可能会遭到伪装
- 所有的请求照单全收,无法阻止DDoS攻击
- 无法验证报文的完整性,可能遭到篡改
-
HTTP+加密+认证+完整性保护==HTTPS
- HTTPS是建立在HTTP上的
- 通过SSL或者TLS认证和加密
- HTTP直接和TCP通信,HTTPS先和SSL通信,SSL再和TCP通信
- SSL采用公开密钥加密,是独立于HTTP的协议
- 客户端可以通过第三方认证机构证明自己的身份
- SSL加密和解密需要耗费大量资源,所以一般用来传递对称私钥,之后使用对称私钥通信
- 上面是对通信过程加密,当然也可对报文主体加密而不加密报文首部,但是此时信息仍然可能被篡改(比如添加干扰使得接收方解析不了)
-
通信过程
-
使用HTTP访问HTTPS网站需要多少RTT?
-
会话恢复
- 一般基于session ID或者session ticket
- 可以把TLS握手的RTT从2降为1
- Session ID 缓存和 Session Ticket 里面保存的是主密钥,而不是会话密钥
- 会话密钥(密钥块)是由主密钥、server_random 和 client_random 数通过 PRF 函数来生成
- 这样每次会话复用的时候再用双方的随机数和主密钥导出会话密钥,从而实现每次加密通信的会话密钥不一样,即使一个会话的主密钥泄露了或者被破解了也不会影响到另一个会话
- 当网站想要接入CDN,但又不想把自己的证书的私钥交给厂家时,需要提供一个key server即可