入门Http和Https
2022-04-09 17:03:50 4 举报
AI智能生成
入门Http和Https,你需要认证学习下这个内容
作者其他创作
大纲/内容
认识HTTP
首先你听的最多的应该就是HTTP是一种超文本传输协议(Hypertext Transfer Protocol) ,
这你一定能说出来,但是这样还不够,假如你是大厂面试官,这不可能是他想要的最终结果,
我们在面试的时候往往把自己知道的尽可能多的说出来,才有和面试官谈价钱的资本。
什么是超文本传输协议?
超文本传输协议可以进行文字分割
超文本(Hypertext)
什么是超文本
【文本】互联网早期,输入的信息只能保存在本地,无法和其他电脑进行交互,保存的信息通
常都以文本即简单字符的形式存在,文本是一种能够被计算机解析的有意义的二进制数据包,
常都以文本即简单字符的形式存在,文本是一种能够被计算机解析的有意义的二进制数据包,
而随着互联网的高速发展,两台电脑之间能够进行数据的传输后,人们不满足只能在两台电脑之间传输文字,
还想要传输图片、音频、视频,甚至点击文字或图片能够进行超链接的跳转,那么文本的语义就被扩
大了, 这种语义扩大后的文本就被称为超文本(Hypertext)
还想要传输图片、音频、视频,甚至点击文字或图片能够进行超链接的跳转,那么文本的语义就被扩
大了, 这种语义扩大后的文本就被称为超文本(Hypertext)
不单单只是本文
它还可以传输图片、音频、视频,甚至点击文字或图片能够进行超链接的跳转。
上面这些概念可以统称为数据
传输(Transfer)
什么是传输
两台计算机之间会形成互联关系进行通信,存储的超文本会被解析成为二进制数据包,
由传输载体负责把二进制数据包由计算机终端传输到另一个终端的过程 称为传输 transfer
传输就是数据需要经过一系列的物理介质从一个端系统传送到另外一个端系统的过程。
传输载体(例如同轴电缆,电话线,光缆)
通常我们把传输数据包的一方称为请求方,把接到二进制数据包的一方称为应答方。
请求方和应答方可以进行互换,请求方也可以作为应答方接受数据,应答方也可以作为请求方请求数据
他们之间的关系如下:
请求方和应答方之间的关系如下:
如图所示,A和B是两个不同的端系统,它们之间可以作为信息交换的载体存在
刚开始时,是A作为请求方请求与B交换信息,B作为响应的一方提供信息;
随着时间的推移,B也可以作为请求方请求A交换信息,那么A也可以作为响应方响应B请求的信息。
协议(Protocol)
什么是协议
协议这个名词不仅局限于互联网范畴,也体现在日常生活中,比如情侣双方约定好在哪个地点吃饭,这
个约定也是一种协议,比如你应聘成功了,企业会和你签订劳动合同,这种双方的雇佣关系也是一种
协议。注意自己一个人对自己的约定不能成为协议,协议的前提条件必须是多人约定。
个约定也是一种协议,比如你应聘成功了,企业会和你签订劳动合同,这种双方的雇佣关系也是一种
协议。注意自己一个人对自己的约定不能成为协议,协议的前提条件必须是多人约定。
那么网络协议是什么呢?
网络协议就是网络中(包括互联网)传递、管理信息的一些规范。
如同人与人之间相互交流是需要遵循一定的规矩一样,计算机之间的相互通信需要共同遵守一定的规则,这些规则就称为网络协议。
没有网络协议的互联网是混乱的,就和人类社会一样,人不能想怎么样就怎么样,你的行为约束是受到
法律的约束的;那么互联网中的端系统也不能自己想发什么发什么,也是需要受到通信协议约束的。
法律的约束的;那么互联网中的端系统也不能自己想发什么发什么,也是需要受到通信协议约束的。
它们之间的关系如下
超文本(Hypertext) 、传输(Transfer) 、协议(Protocol)
按照范围的大小协议>传输>超文本。
你说你懂互联网,那这些你知道么?
https://mp.weixin.qq.com/s?__biz=MzkwMDE1MzkwNQ==&mid=2247496041&idx=1&sn=f8fe490a755a4e373fa36c8114467493&source=41#wechat_redirect
什么是HTTP?HTTP是怎么定义的?
HTTP是一种超文本传输协议(Hypertext Transfer Protocol)协议
HTTP是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
HTTP的优点和缺点
HTTP的优点
简单灵活易扩展
HTTP最重要也是最突出的优点是简单、灵活、易于扩展。
HTTP的协议比较简单
它的主要组成就是header+body
头部信息也是简单的文本格式, 而且HTTP的请求报文根据英文也能猜出来个大概的意思,
降低学习门槛, 能够让更多的人研究和开发HTTP应用
所以, 在简单的基础上, HTTP协议又多了灵活和易扩展的优点。
HTTP协议里的每一个核心组成要素都没有被制定死,允许开发者任意定制、扩充或解释,给予了浏览器和服务器最大程度的信任和自由。
核心组成要素
请求方法、URI、状态码、原因短语、头字段等
应用广泛、环境成熟
因为过于简单, 普及, 因此应用很广泛。
因为HTTP协议本身不属于一种语言, 它并不限定某种编程语言或者操作系统,所以天然具有跨语言、跨平台的优越性。
而且,因为本身的简单特性很容易实现,所以几乎所有的编程语言都有HTTP调用库和外围的开发测试工具。
陆着移动互联网的发展, HTTP的触角已经延仲到了世界的每一个角落, 从简单的Web页面到复杂的
JSON、XML数据, 从台式机上的浏览器到手机上的各种APP、新闻、论坛、购物、手机游戏, 你很难
找到一个没有使用HTTP的地方。
JSON、XML数据, 从台式机上的浏览器到手机上的各种APP、新闻、论坛、购物、手机游戏, 你很难
找到一个没有使用HTTP的地方。
无状态
无状态其实既是优点又是缺点。
因为服务器没有记忆能力,所以就不需要额外的资源来记录状态信息,
不仅实现上会简单一些, 而且还能减轻服务器的负担, 能够把更多的CPU和内存用来对外提供服务。
HTTP的缺点
无状态
既然服务器没有记忆能力,它就无法支持需要连续多个步骤的事务操作。
每次都得问一遍身份信息,不仅麻烦, 而且还增加了不必要的数据传输量。
由此出现了Cookie技术。
明文传输
HTTP协议里还有一把优缺点一体的双刃剑, 就是明文传输。
明文意思就是协议里的报文(准确地说是header部分) 不使用二进制数据, 而是用简单可阅读的文本形式
对比TCP、UDP二进制协议
优点:
不需要借助任何外部工具
用浏览器、Wire shark或者tcpdump抓包后
直接用肉眼就可以很容易地查看或者修改, 为开发调试工作带来极大的便利。
缺点:
就是不安全,可以被监听和被窥探。
因为无法判断通信双方的身份,不能判断报文足否被更改过。
性能
HTTP的性能不算差, 但不完全适应现在的互联网, 还有很大的提升空间。
与HTTP有关的组件
随着网络世界演进, HTTP协议已经几乎成为不可替代的一种协议,
在了解了HTTP的基本组成后, 下面再来带你进一步认识一下HTTP协议。
两种网络模型
网络是一个复杂的系统,不仅包括大量的应用程序、端系统、通信链路、分组交换机等,
还有各种各样的协议组成,那么现在我们就来聊一下网络中的协议层次。
为了给网络协议的设计提供一个结构, 网络设计者以分层(Layer) 的方式组织协议, 每个协议属于层次模型之一。
每一层都是向它的上一层提供服务(service) , 即所谓的服务模型(service model) .
每个分层中所有的协议称为协议栈(protocol stack) .
采用自上而下的方法研究其原理,也就是应用层,物理层的方式。
五层网络协议
TCP/IP网络模型, 一般是五层模型
五层网络协议的示意图如下
五层网络协议的示意图如下
但是也可以分为四层,就是把链路层和物理层都表示为网络接口层
四层网络协议的示意图如下:
四层网络协议的示意图如下:
因特网的协议栈由五个部分组成
应用层
应用层是网络应用程序和网络协议存放的分层, 因特网的应用层包括许多协议,
例如学web离不开的HTTP, 电子邮件传送协议SMTP、端系统文件上传协议FTP、还有进行域名解析的DNS协议。
应用层协议分布在多个端系统上, 一个端系统应用程序与另外一个端系统应用程序交换信息分组,
把位于应用层的信息分组称为报文(message) 。
运输层
因特网的运输层在应用程序断点之间传送应用程序报文,,
在这一层主要有两种传输协议
TCP
UDP
利用这两者中的任何一个都能够传输报文, 不过这两种协议有巨大的不同,
把运输层的分组称为报文段(segment)
网络层
因特网的网络层负责将称为数据报(datagram) 的网络分层从一台主机移动到另一台主机。
网络层一个非常重要的协议是IP协议,所有具有网络层的因特网组件都必须运行IP协议,
IP协议是一种网际协议,除了IP协议外,网络层还包括一些其他网际协议和路由选择协议,
一般把网络层就称为IP层,由此可知IP协议的重要性。
链路层
现在有应用程序通信的协议,有了给应用程序提供运输的协议,还有了用于约定发送位置的IP协
议,那么如何才能真正的发送数据呢?
议,那么如何才能真正的发送数据呢?
为了将分组从一个节点(主机或路由器)运输到另一个节点,网络层必须依靠链路层提供服务。
链路层的例子包括以太网、WiFI和电缆接入的DOCSIS协议
因为数据从源目的地传送通常需要经过几条链路,一个数据包可能被沿途不同的链路层协议处理
把链路层的分组称为(frame)
物理层
虽然链路层的作用是将顿从一个端系统运输到另一个端系统
而物理层的作用是将帧中的一个个比特从一个节点运输到另一个节点,
物理层的协议仍然使用链路层协议,
这些协议与实际的物理传输介质有关,
例如,以太网有很多物理层协议:关于双绞铜线、关于同轴电缆、关于光纤等等。
OSI模型
计算网络协议模型不是唯一的协议栈,
ISO(国际标准化组织) 提出来计算机网络应该按照7层来组织,那么7层网络协议栈与5层的区别在哪里?
七层网络协议的示意图如下
7层网络协议栈图解
OSI七层网络模型, 它就是在五层协议之上加了表示层和会话层
从图中可以一眼看出, OSI要比上面的网络模型多了表示层和会话层, 其他层基本一致。
表示层主要包括数据压缩和数据加密以及数据描述,数据描述使得应用程序不必担心计算机内部存储格式的问题
而会话层提供了数据交换的定界和同步功能,包括建立检查点和恢复方案。
对比运输层中,TCP协议与UDP协议的主要区别
TCP协议
TCP协议是什么
TCP的全称是Transmission Control Protocol, 传输控制协议,
它能够帮助你确定计算机连接到Interet以及它们之间的数据传输。
通过三次握手来建立TCP连接, 三次握手就是用来启动和确认TCP连接的过程。
一旦连接建立后, 就可以发送数据了, 当数据传输完成后, 会通过关闭虚拟电路来断开连接。
TCP的主要特点
TCP支持错误重传机制
TCP能够提供错误校验和, 甄别有害的数据包。
TCP会进行错误校验, 并能够进行错误恢复
TCP支持拥塞控制
提供了拥塞机制来控制网络传输
因此当网络拥塞时,会抑制其传输速率。
能够在网络拥堵的情况下延迟发送
TCP是面向连接的协议
向它的应用程序提供了面向连接的服务,
TCP能够确保连接的建立和数据包的发送
TCP在发送数据前先需要建立连接, 然后再发送数据
TCP会按照特定顺序重新排列数据包
TCP传输的速度比较慢
TCP的头部字节有20字节
TCP是重量级的, 在发送任何用户数据之前, TCP需要三次握手建立连接。
TCP有发送确认
TCP会使用握手协议, 例如SYN, SYN-ACK, ACK
TCP是可靠的, 因为它可以确保将数据传送到路由器。
它能够控制并确认报文是否到达
UDP协议
UDP协议是什么
UDP的全称是User Datagram Protocol, 用户数据报协议。
它不需要所谓的握手操作, 从而加快了通信速度,允许网络上的其他主机在接收方同意通信之前进行数据传输。
数据报是与分组交换网络关联的传输单元。
UDP协议的特点
UDP是无连接的协议
向它的应用程序提供了无连接服务。
UDP无需建立连接就可以直接发送大量数据
UDP能够发送大量的数据包
没有流量控制
UDP不具备可靠性的特征
在UDP中不能保证将数据传送到目标。
UDP能够支持容忍数据包丢失的带宽密集型应用程序
也没有拥塞控制
UDP具有低延迟的特点
UDP能够允许DNS查找, DNS是建立在UDP之上的应用层协议。
UDP的传输会更快
UDP数据包没有固定顺序, 所有数据包都相互独立
UDP的头部字节只需要8个字节
UDP是轻量级的, 没有跟踪连接, 消息排序等.
UDP也会错误检查, 但会丢弃错误的数据包。
UDP没有发送确认
无握手协议
相同点
TCP和UDP都位于计算机网络模型中的运输层
它们负责传输应用层产生的数据
图解TCP协议与UDP协议的主要区别
图解TCP协议与UDP协议的主要区别
浏览器
就如同各大邮箱使用电子邮件传送协议SMTP一样, 浏览器是使用HTTP协议的主要载体,
说到浏览器,你能想起来几种?
随着网景大战结束后,浏览器迅速发展,至今已经出现过的浏览器主要有
说到浏览器,你能想起来几种?
浏览器正式的名字叫做WebBrowser, 顾名思义, 就是检索、查看互联网上网页资源的应用程序,
名字里的Web, 实际上指的就是WorLdWide Web, 也就是万维网,
一个浏览器发起请求和接受响应的过程
在地址栏输入URL(即网址) , 浏览器会向DNS(域名服务器) 提供网址, 由它来完成URL到IP地址的映射
然后将请求你的请求提交给具体的服务器, 在由服务器返回我们要的结果(以HTML编码格式返回给浏览器)
浏览器执行HTML码, 将结果显示在浏览器的正文, 这就是一个浏览器发起请求和接受响应的过程.
Web服务器
Web服务器的正式名称叫做WebServer, Web服务器一般指的是网站服务器
上面说到浏览器是HTTP请求的发起方, 那么Web服务器就是HTTP请求的应答方,
Web服务器可以向浏览器等Web客户端提供文档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。
目前最主流的三个Web服务器是Apache、Nginx、IIS。
CDN
CDN的全称是Content Delivery Network, 即内容分发网络
它应用了HTTP协议里的缓存和代理技术, 代替源站响应客户端的请求,
CDN是构建在现有网络基础之上的网络, 它依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞, 提高用户访问响应速度和命中率。
CDN的关键技术主要有
内容存储
分发技术
以在亚马逊买书为例
打比方说,你要去亚马逊上买书,
之前,你只能通过购物网站购买后从美国发货过海关等重重关卡送到你的家里,
现在,在中国建立一个亚马逊分基地,你就不用通过美国进行邮寄,从中国就能把书尽快给你送到。
WAF
WAF是一种Web应用程序防护系统(Web Application Firewall, 简称WAF)
它是一种通过执行一系列针对HTTP/HTTPS的安全策路来专门为Web应用提供保护的一款产品
它是应用层面的防火墙, 专门检测HTTP流量, 是防护Web应用的安全技术。
WAF通常位于Web服务器之前, 可以阻止如SQL注入, 跨站脚本等攻击,
目前应用较多的一个开源项目是Mod Security, 它能够完全集成进Apache或Nginx。
WebService
WebService是一种Web应用程序, WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
WebService是一种由W3C定义的应用服务开发规范, 使用client-server主从架构
通常使用WSDL定义服务接口, 使用HTTP协议传输XML或SOAP消息,
它是一个基于Web(HTTP) 的服务架构技术,既可以运行在内网,也可以在适当保护后运行在外网。
HTML
HTML称为超文本标记语言, 是一种标识性的语言,
它包括一系列标签, 通过这些标签可以将网络上的文档格式统一, 使分散的Internet资源连接为一个逻辑整体
HTML文本是由HTML命令组成的描述性文本, HTML命令可以说明文字, 图形、动画、声音、表格、链接等。
Web页面构成
Web页面(Webpage) 也叫做文档, 是由一个个对象组成的。
一个对象(Object) 只是一个文件, 比如一个HTML文件、一个JPEG图形、一个Java小程序或一个视频片段, 它们在网络中可以通过URL地址寻址。
多数的Web页面含有一个HTML基本文件以及几个引用对象。
举个例子, 如果一个Web页面包含HTML文件和5个JPEG图形, 那么这个Web页面就有6个对象:
一个HTML文件和5个JPEG图形, HTML基本文件通过URL地址引用页面中的其他对象。
一个HTML文件和5个JPEG图形, HTML基本文件通过URL地址引用页面中的其他对象。
与HTTP有关的协议
在互联网中, 任何协议都不会单独的完成信息交换, HTTP也一样。
虽然HTTP属于应用层的协议, 但是它仍然需要其他层次协议的配合完成信息的交换,
那么在完成一次HTTP请求和响应的过程中, 需要些协议的配合呢?一起来看一下
TCP/IP
TCP/IP协议你一定听过, TCP/IP一般称之为协议族, 什么意思呢?
就是TCP/IP协议簇中,不仅仅只有TCP协议和IP协议, 它是一系列网络通信协议的统称。
而其中最核心的两个协议就是TCP/IP协议, 其他的还有UDP、ICMP、ARP等等, 共同构成了一个复杂但有层次的协议栈。
TCP协议
TCP协议的全称是Transmission Control Protocol的缩写, 意思是传输控制协议
HTTP使用TCP作为通信协议, 这是因为TCP是一种可靠的协议, 而可靠能保证数据不丢失,
IP协议
IP协议的全称是Internet Protocol的缩写, 它主要解决的是通信双方寻址的问题。
IP协议使用IP地址来标识互联网上的每一台计算机
可以把IP地址想象成为你手机的电话号码,你要与他人通话必须先要知道他人的手机号码, 计算机网络中信息交换必须先要知道对方的IP地址。
DNS
你有没有想过,为什么你可以通过键入www.google.com就能够获取你想要的网站?
诞生原因
互联网中识别主机的方式有两种
通过主机名
通过IP地址
计算机网络中的每个端系统都有一个IP地址存在, 而把IP地址转换为便于人类记忆的协议就是DNS协议
人喜欢用名字的方式进行记忆,但是通信链路中的路由却喜欢定长、有层次结构的IP地址
一种能够把主机名到IP地址的转换服务, 这种服务就是由DNS提供的。
一种能够把主机名到IP地址的转换服务
它作为将域名和IP地址相互映射的一个分布式数据库,能够便人更方便地访问互联网。
DNS介绍
DNS的全称是域名系统(DomainName System, 缩写:DNS)
DNS的全称是DomainName System域名系统
DNS运行在UDP上, 使用53端口。
DNS是一种分层数据库, 它的主要层次结构如下
DNS是一种由分层的DNS服务器实现的分布式数据库
一般域名服务器的层次结构主要是以上三种
本地DNS服务器(Local DNS server)
除此之外, 还有另一类重要的DNS服务器, 它是本地DNS服务器(Local DNS server)
严格来说, 本地DNS服务器并不属于上述层次结构
但是本地DNS服务器又是至关重要的。
每个ISP ( Internet Service Provider) 比如居民区的ISP,或者一个机构的ISP,都有一台本地DNS服务器。
当主机和ISP进行连接时, 该ISP会提供一台主机的IP地址, 该主机会具有一台或多台其本地DNS服务器的IP地址。
通过访问网络连接, 用户能够容易的确定DNS服务器的IP地址。
当主机发出DNS请求后, 该请求被发往本地DNS服务器, 它起着代理的作用, 并将该请求转发到DNS服务器层次系统中
工作流程
首先, 查询请求会先找到本地DNS服务器来查询是否包含IP地址,
如果本地DNS无法查询到目标IP
地址, 就会向根域名服务器发起一个DNS查询。
【递归查询】如果根域名服务器,无法告知本地DNS服务器下一步需要访问哪个顶级域名服务器, 就会使用递归查询;
【迭代查询】如果根域名服务器,能够告知DNS服务器下一步需要访问的顶级域名服务器, 就会使用迭代查询。
在由根域名服务器→顶级域名服务器→权威DNS服务器后, 由权威服务器告诉本地服务器目标IP地址, 再有本地DNS服务器告诉用户需要访问的IP地址。
DNS涉及两种查询方式
递归查询(Recursive query)
如果根域名服务器,无法告知本地DNS服务器下一步需要访问哪个顶级域名服务器, 就会使用递归查询;
迭代查询(Iteration query)
如果根域名服务器,能够告知DNS服务器下一步需要访问的顶级域名服务器, 就会使用迭代查询。
《计算机网络:自顶向下方法》竟然没有给出递归查询和代查询的区别,找了一下网上的资料大概明白了下。
URI/URL/URN
我们上面提到,你可以通过输入www.google.com地址来访问谷歌的官网,那么这个地址有什么规定
吗?我怎么输都可以?AAA.BBB.CCC是不是也行?当然不是的, 你输入的地址格式必须要满足URI
的规范。
吗?我怎么输都可以?AAA.BBB.CCC是不是也行?当然不是的, 你输入的地址格式必须要满足URI
的规范。
URI
全称是(Uniform Resource Id entier)
中文名称是统一资源标识符
使用它就能够唯一地标记互联网上资源。
URL
全称是(Uniform Resource Locator)
中文名称是统一资源定位符, 也就是俗称的网址
它实际上是URI的一个子集
URN
统一资源名称
URI不仅包括URL, 还包括URN(统一资源名称)
三者之间的关系
三者之间的关系
TCP三次握手 和 TCP四次挥手
分别对应TCP的连接和释放过程
TCP三次握手
图解TCP三次握手
认识几个概念
图解
SYN
它的全称是Synchronize Sequence Numbers, 同步序列编号,
是TCP/IP建立连接时使用的握手信号, 在客户机和服务器之间建立TCP连接时, 首先会发送的一个信号。
客户端在接受到SYN消息时, 就会在自己的段内生成一个随机值X.
这个消息是用来初始化和建立连接的。
SYN-ACK
本地的SYN消息和较早的ACK数据包
服务器收到SYN后, 打开客户端连接, 发送一个SYN-ACK作为答复。
确认号设置为比接收到的序列号多一个,即X+1,服务器为数据包选择的序列号是另一个随机数Y.
ACK
帮助对方确认收到的SYN消息
Acknowledge character, 确认字符, 表示发来的数据已确认接收无误。
最后, 客户端将ACK发送给服务器。
序列号被设置为所接收的确认值即Y+1.
FIN
用来断开连接
用生活中的例子解释
小明-客户端
小红-服务端
子主题
【SYN】小明给小红打电话,接通了后,小明说喂,能听到吗
这就相当于是连接建立。
【SYN-ACK】小红给小明回应,能听到,你能听到我说的话吗
这就相当于是请求响应
【ACK】小明听到小红的回应后,好的
这相当于是连接确认
在这之后小明和小红就可以通话/交换信息了。
TCP四次挥手
在连接终止阶段使用四次挥手,连接的每一端都会独立的终止。
图解TCP四次挥手过程
图解TCP四次挥手过程
TCP四次挥手过程
第一步【FIN】
首先, 客户端应用程序决定要终止连接(这里服务端也可以选择断开连接) 。
这会使客户端将FIN发送到服务器, 并进入FIN_WAIT_1状态。
当客户端处于FIN_WAIT_1状态时, 它会等待来自服务器的ACK响应,
第二步【ACK】
当服务器收到FIN消息时, 服务器会立刻向客户端发送ACK确认消息。
当客户端收到服务器发送的ACK响应后, 客户端就进入FIN_WAIT_2状态, 然后等待来自服务器的FIN消息
第三步【FIN】
服务器发送ACK确认消息后, 一段时间(可以进行关闭后) 会发送FIN消息给客户端, 告知客户端可以进行关闭。
第四步【ACK】
当客户端收到从服务端发送的FIN消息时, 客户端就会由FIN_WAIT_2状态变为TIME_WAIT状态,
处于TIME WAIT状态的客户端允许重新发送ACK到服务器为了防止信息丢失。
处于TIME WAIT状态的客户端允许重新发送ACK到服务器为了防止信息丢失。
客户端在TIME WAIT状态下花费的时间取决于它的实现, 在等待一段时间后, 连接关闭,
客户端上所有的资源(包括端口号和缓冲区数据)都被释放
客户端上所有的资源(包括端口号和缓冲区数据)都被释放
用生活中的例子解释
小明-客户端
小红-服务端
小明对小红说,我所有的东西都说完了,我要挂电话了。
小红说,收到,我这边还有一些东西没说。
经过若干秒后,小红也说完了,小红说,我说完了,现在可以挂断了
小明收到消息后,又等了若干时间后,挂断了电话。
地址栏输入URL发生了什么
第一步
首先, 你需要在浏览器中的URL地址上, 输入你想访问的地址
你应该访问不到的,对不对~
第二步
浏览器会根据你输入的URL地址, 去查找域名是否被本地DNS缓存, 不同浏览器对DNS的设置不同
如果浏览器缓存了你想访问的URL地址, 那就直接返回ip
如果没有缓存你的URL地址, 浏览器就会发起系统调用来查询本机hosts文件是否有配置ip地址,
如果找到, 直接返回。如果找不到, 就向网络中发起一个DNS查询。
DNS是什么(略)
DNS的工作流程
首先, 查询请求会先找到本地DNS服务器来查询是否包含IP地址,
如果本地DNS无法查询到目标IP
地址, 就会向根域名服务器发起一个DNS查询。
【递归查询】如果根域名服务器,无法告知本地DNS服务器下一步需要访问哪个顶级域名服务器, 就会使用递归查询;
【迭代查询】如果根域名服务器,能够告知DNS服务器下一步需要访问的顶级域名服务器, 就会使用迭代查询。
在由根域名服务器→顶级域名服务器→权威DNS服务器后, 由权威服务器告诉本地服务器目标IP地址, 再有本地DNS服务器告诉用户需要访问的IP地址。
第三步
浏览器需要和目标服务器建立TCP连接, 需要经过三次握手的过程
在建立连接后, 浏览器会向目标服务器发起HTTP-GET请求, 包括其中的URL, HTTP 1.1后默认使用长连接,只需要一次握手即可多次传输数据。
如果目标服务器只是一个简单的页面,就会直接返回。
但是对于某些大型网站的站点,往往不会直接返回主机名所在的页面,而会直接重定向。
返回的状态码就不是200,而是301,302以3开头的重定向码,
浏览器在获取了重定向响应后, 在响应报文中Location项找到重定向地址, 浏览器重新第一步访问即可。
然后浏览器重新发送请求, 携带新的URL, 返回状态码200OK, 表示服务器可以响应请求, 返回报文
HTTP请求响应过程
你是不是很好奇,当你在浏览器中输入网址后,到底发生了什么事情?你想要的内容是如何展现出来的?
让我们通过一个例子来探讨一下, 假设访问的URL地址为http://www.someSchool.edu/someDepartment/home.index,
当我们输入网址并点击回车时,浏览器内部会进行如下操作:
DNS服务器会首先进行域名的映射,找到访问www.someSchool.edu所在的地址,然后HTTP客
户端进程在80端口发起一个到服务器ww.some 5chool.edu的TCP连接(80端口是HTTP
的默认端口),在客户和服务器进程中都会有一个套接字与其相连。
户端进程在80端口发起一个到服务器ww.some 5chool.edu的TCP连接(80端口是HTTP
的默认端口),在客户和服务器进程中都会有一个套接字与其相连。
HTTP客户端通过它的套接字向服务器发送一个HTTP请求报文。该报文中包含了路径
some Department/home.index的资源, 我们后面会详细讨论HTTP请求报文
some Department/home.index的资源, 我们后面会详细讨论HTTP请求报文
HTTP服务器通过它的套接字接受该报文, 进行请求的解析工作, 并从其存储器(RAM或磁盘) 中
检索出对象www.someSchool.edu/someDepartment/home.index,然后把检索出来的对象进
行封装, 封装到HTTP响应报文中, 井通过套接字向客户进行发送。
检索出对象www.someSchool.edu/someDepartment/home.index,然后把检索出来的对象进
行封装, 封装到HTTP响应报文中, 井通过套接字向客户进行发送。
HTTP服务器随即通知TCP断开TCP连接, 实际上是需要等到客户接受完响应报文后才会断开
TCP连接。
TCP连接。
HTTP客户端接受完响应报文后, TCP连接会关闭。HTTP客户端从响应中提取出报文中是一个
HTML响应文件, 并检查该HTML文件, 然后循环检查报文中其他内部对象。
HTML响应文件, 并检查该HTML文件, 然后循环检查报文中其他内部对象。
检查完成后, HTTP客户端会把对应的资源通过显示器呈现给用户,
至此,键入网址再按下回车的全过程就结束了
上述过程描述的是一种简单的请求-响应全过程,真实的请求-响应情况可能要比上面描述的过程复杂很多.
上面描述了一下HTTP的请求响应过程, 流程比较简单, 但是凡事就怕认真, 你这一认真, 就能拓展出很多东西
HTTP请求特征
从上面整个过程中我们可以总结出HTTP进行分组传输是具有以下特征
支持客户-服务器模式
简单快速
客户向服务器请求服务时, 只需传送请求方法和路径, 请求方法常用的有GET、HEAD、POST。
每种方法规定了客户与服务器联系的类型不同。
由于HTTP协议简单, 使得HTTP服务器的程序规模小, 因而通信速度很快
灵活
HTTP允许传输任意类型的数据对象。
正在传输的类型由Content-Type加以标记。
无连接
无连接的含义是限制每次连接只处理一个请求。
服务器处理完客户的请求,并收到客户的应答后,即断开连接。
采用这种方式可以节省传输时间。
无状态
HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。
缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
另一方面,在服务器不需要先前信息时它的应答就较快。
详解HTTP报文
HTTP报文是什么样的, 它的组成格式是什么?
HTTP协议主要由三大部分组成
起始行(start line)
描述请求或响应的基本信息
头部字段(header)
使用key-value形式更详细地说明报文;
消息正文(entity)
实际传输的数据, 它不一定是纯文本, 可以是图片、视频等二进制数据。
图解HTTP协议的三大组成部分
用一幅图来表示
Header 与 Body
其中起始行和头部字段并成为请求头或者销应头, 统称为Header;
消息正文也叫做实体, 称为body.
HTTP协议规定每次发送的报文必须要有Header, 但是可以没有body,
也就是说头信息是必须的, 实体信息可以没有, 而且在header和body之间必须要有一个空行(CRLF)
使用上面的那个例子来看一下http的请求报文
http的请求报文
如图,这是http://ww.some5chool.edu/someDepartment/home.index请求的请求头,通过观察这个HTTP报文就能够学到很多东西,
首先, 看到报文是用普通ASCII文本书写的, 这样保证人能够可以看懂。
然后,每一行和下一行之间都会有换行,而且最后一行(请求头部后)再加上一个回车换行符。
每个报文的起始行都是由三个字段组成
图解每个报文的起始行都是由三个字段组成
图解每个报文的起始行都是由三个字段组成
(1)Http请求方法
HTTP请求方法一般分为8种
GET获取资源
GET方法用来请求访问已被URI识别的资源。
指定的资源经服务器端解析后返回响应内容。
也就是说,如果请求的资源是文本,那就保持原样返回;
POST传输实体
虽然GET方法也可以传输主体信息,
但是便于区分, 一般不用GET传输实体信息, 反而使用POST传输实体信息,
PUT传输文件
PUT方法用来传输文件。
就像FTP协议的文件上传一样, 要求在请求报文的主体中包含文件内容, 然后保存到请求URI指定的位置。
但是, 鉴于HTTP的PUT方法自身不带验证机制, 任何人都可以上传文件, 存在安全性问题, 因此一般的Web网站不使用该方法。
若配合Web应用程序的验证机制, 或架构设计采用REST(REpresentational S tote Transfer.表征状态转移) 标准的同类Web网站, 就可能会开放使用PUT方法。
HEAD获得响应首部
HEAD方法和GET方法一样, 只是不返回报文主体部分
用于确认URI的有效性及资源更新的日期时间等.
DELETE删除文件
DELETE方法用来州除文件, 是与PUT相反的方法。
DELETE方法按请求URI删除指定的资源
OPTIONS询问支持的方法
OPTIONS方法用来查询针对请求URI指定的资源支持的方法。
TRACE追踪路径
TRACE方法是让Web服务器端将之前的请求通信环回给客户端的方法。
CONNECT要求用隧道协议连接代理
CONNECT方法要求在与代理服务器通信时建立隧道, 实现用隧道协议进行TCP通信。
主要使用SSL和TLS协议把通信内容加密后经网络隧道传输。
SSL(Secure Sockets Layer, 安全套接层)
TLS(Transport Layer Security, 传输层安全)
一般最常用的方法也就是GET方法和POST方法, 其他方法暂时了解即可。
下面是HTTP 1.0和HTTP 1.1支持的方法清单
HTTP 1.0和HTTP 1.1支持的方法清单
(2)URL字段(HTTP请求URL)
HTTP协议使用URI定位互联网上的资源。
正是因为URI的特定功能, 在互联网上任意位置的资源都能访问到, URL带有请求对象的标识符。
在上面的例子中, 浏览器正在请求对象/somedir/page.html的资源。
再通过一个完整的域名解析一下URL
比如http://ww.example.com:80/path/to/myfile.html?key l=value 1&key 2=value 2#Somewhere In The Document
这个URL比较繁琐了吧, 你把这个URL搞懂了其他的URL也就不成问题了。
请求URL所必须包含的部分
http
首先出场的是http
http://告诉浏览器使用何种协议。对于大部分Web资源, 通常使用HTTP协议或其安全版本,HTTPS协议。
另外, 浏览器也知道如何处理其他协议。
例如, mailto:协议指示浏览器打开邮件客户端:ftp:协议指示浏览器处理文件传输。
主机
第二个出场的是主机
wmw.example.com既是一个域名, 也代表管理该域名的机构。
它指示了需要向网络上的哪一台主机发起请求。
当然, 也可以直接向主机的IPaddress地址发起请求。但直接使用IP地址的场景并不常见。
端口
第三个出场的是端口
两个主机之间要发起TCP连接需要两个条件, 主机+端口。
它表示用于访问Web服务器上资源的入口。
如果访问的该Web服务器使用HTTP协议的标准端口(HTTP为80, HTTPS为443) 授予对其资源的访问权限, 则通常省此部分。
否则端口就是URI必须的部分。
URL具体请求资源路径
路径
路径
/path/to/my fite.html是Web服务器上资源的路径。
以端口后面的第一个/开始, 到?号之前结束, 中间的每一个/都代表了层级(上下级) 关系, 这个URL的请求资源是一个html页面。
查询参数
查询参数
?key l=value l&keyZ=value 2是提供给Web服务器的额外参数。
如果是GET请求, 一般带有请求URL参数,
如果是POST请求, 则不会在路径后面直接加参数。
这些参数是用&符号分隔的键/值对列表。
key 1=value 1是第一对, key 2=value 2是第二对参数
锚点
锚点
#Somewhere In The Document是资源本身的某一部分的一个锚点。
锚点代表资源内的一种"书签", 它给予浏览器显示位于该“加书签“点的内容的指示。
例如,
在HTML文档上, 浏览器将滚动到定义锚点的那个点上;
在视频或音频文档上,浏览器将转到锚点代表的那个时间。
值得注意的是#号后面的部分,也称为片段标识符,永远不会与请求一起发送到服务器。
(3)HTTP版本字段
HTTP 1.0
HTTP 1.0是在1996年引入的, 从那时开始, 它的普及率就达到了惊人的效果,
HTTP 1.0仅仅提供了最基本的认证, 这时候用户名和密码还未经加密, 因此很容易收到窥探。
HTTP 1.0被设计用来使用短链接, 即每次发送数据都会经过TCP的三次握手和四次挥手, 效率比较低。
HTTP 1.0只使用header中的If-Modified-Since和Expires作为缓存失效的标准。
HTTP 1.0不支持断点续传, 也就是说, 每次都会传送全部的页面和数据,
HTTP 1.0认为每台计算机只能绑定一个IP, 所以请求消息中的URL并没有传递主机名(hostname) 。
HTTP 1.0被设计用来使用短链接, 即每次发送数据都会经过TCP的三次握手和四次挥手, 效率比较低。
HTTP 1.0只使用header中的If-Modified-Since和Expires作为缓存失效的标准。
HTTP 1.0不支持断点续传, 也就是说, 每次都会传送全部的页面和数据,
HTTP 1.0认为每台计算机只能绑定一个IP, 所以请求消息中的URL并没有传递主机名(hostname) 。
HTTP 1.1
HTTP 1.1是HTTP 1.0开发三年后出现的, 也就是1999年, 它做出了以下方面的变化
HTTP 1.1便用了摘要算法来进行身份验证
HTTP 1.1默认使用长连接, 长连接就是只需一次建立就可以传输多次数据, 传输完成后, 只需要
一次切断连接即可。长连接的连接时长可以通过请求头中的keep-alive来设置
HTTP 1.1中新增加了E-tag, If-Unmodified-Since, If-Match, If-None-Match等缓存控制标头来控制缓存失效。
HTTP 1.1支持断点续传, 通过使用请求头中的Range来实现。
HTTP 1.1使用了虚拟网络, 在一台物理服务器上可以存在多个虚拟主机(Multi-homed WebServers) , 并且它们共享一个IP地址。
HTTP 1.1默认使用长连接, 长连接就是只需一次建立就可以传输多次数据, 传输完成后, 只需要
一次切断连接即可。长连接的连接时长可以通过请求头中的keep-alive来设置
HTTP 1.1中新增加了E-tag, If-Unmodified-Since, If-Match, If-None-Match等缓存控制标头来控制缓存失效。
HTTP 1.1支持断点续传, 通过使用请求头中的Range来实现。
HTTP 1.1使用了虚拟网络, 在一台物理服务器上可以存在多个虚拟主机(Multi-homed WebServers) , 并且它们共享一个IP地址。
HTTP 2.0
HTTP 2.0是2015年开发出来的标准, 它主要做的改变如下
头部压缩
由于HTTP 1.1经常会出现User-Agent、Cookie、Accept、Server、Range等字段可能会占用几百甚至几千字节
而Body却经常只有几十字节, 所以导致头部偏重。
HTTP 2.0使用HPACK算法进行压缩
二进制格式
HTTP 2.0使用了更加靠近TCP/IP的二进制格式, 而抛弃了ASCII码, 提升了解析效率
强化安全
由于安全已经成为重中之重, 所以HTTP 2.0一般都跑在HTTPS上。
多路复用
即每一个请求都是是用作连接共享。
一个请求对应一个id,这样一个连接上可以有多个请求。
HTTP/1.1 Baseline 与 HTTP/2 Multiplexing
子主题
HTTP Get和Post区别
HTTP中包括许多方法, Get和Post是HTTP中最常用的两个方法
基本上使用HTTP方法中有99%都是在使用Get方法和Post方法
所以有必要我们对这两个方法有更加深刻的认识。
get方法
一般用于请求
比如你在浏览器地址栏输入www.cxuanblog.com其实就是发送了一个get请求
它的主要特征是请求服务器返回资源
get相当于一个是pulll拉的操作
get方法是不安全的
因为在发送请求的过程中, 请求参数会拼在URL后面, 从而导致容易被攻击者窃取,对你的信息造成破坏和伪造;
长度限制方面
get请求的URL有长度限制
cache问题
·get请求会被浏览器主动cache
浏览器反复的回退/前进操作
get请求在浏览器反复的回退/前进操作是无害的
TCP数据包数
get请求在发送过程中会产生一个TCP数据包
对于get方式的请求, 浏览器会把http header和data一并发送出去, 服务器响应200(返回数据)
post方法
一般用于<form>表单的提交
而post方法一般用于<form>表单的提交
相当于是把信息提交给服务器, 等待服务器作出响应
而post相当于是一个push推的操作
post方法相对安全些
而post方法是把参数放在请求体body中的, 这对用户来说不可见,
post方法相对安全些
长度限制方面
而post请求会把参数和值放在消息体中, 对数据长度没有要求。
cache问题
post不会被浏览器主动cache, 除非手动设置。
浏览器反复的回退/前进操作
post操作会再次提交表单请求。
TCP数据包数
post在发送过程中会产生两个TCP数据包。
对于post, 浏览器会先发送header, 服务器响应100continue, 浏览器再发送data, 服务器响应200ok(返回数据)
HTTP标头
通用标头
HTTP通用标头之所以这样命名, 是因为与其他三个类别不同,
它们不是限定于特定种类的消息或者消息组件(请求, 响应或消息实体) 的,
HTTP通用标头主要用于传达有关消息本身的信息, 而不是它所携带的内容。
它们提供一般信息并控制如何处理和处理消息。
尽管通用标头不会限定于是请求还是响应报文,但是某些通用标头大部分或全部用于一种特定类型的请求中。
也就是说,如果某个通用标头出现在请求报文中,那么大部分通用标头都会显示在该请求报文中。响应报文也是一样的。
常见的通用标头
Cache-Control
缓存(Cache)是什么?
缓存(Cache) 是计算机领域里的一个重要概念, 是优化系统性能的利器。
不仅计算机中的CPU为了提高指令执行效率从而选择使用寄存器作为辅助,计算机网络同样存在缓存
下面就来介绍一下计算机网络中的缓存。
Cache-Control介绍
Cache-Control是通用标头的指令, 它能够管理如何对HTTP的请求或者响应使用缓存.
控制缓存的行为
Cache-Control是一个通用标头, 他可以出现在请求标头和响应标头中
Cache-Control的种类比较多,虽然说这是一个通用标头,但是又一些特性是请求标头具有的,有一些是响应标头才有的。
因为计算机网络中是可以有第三者出现的,也就是缓存服务器,这个指令通过影响请求/响应中的缓存服务器从而达到控制缓存的目的;
不仅有缓存服务器,还有浏览器内部缓存也会影响链路的缓存。
这个标头中可以出现许多单独的指令, 其详细信息可以在RFC 2616中找到, 即使这是常规标头, 某些指令也只能出现在请求或响应中。
下表提供了一个Cache-Control选项的总结并告诉你如何去使用
Cache-Control选项的总结
请注意, 在Cache-Control标头中只能出现一个指令, 但是在消息中可以出现多个这样的标头。
Cache-Control选项有四种分类
(1)可缓存性
不缓存过期资源no-cache
所有的请求都会直接到达服务器,由服务器来下载资源并返回。
不缓存过期资源即浏览器和代理不会缓存过期资源,客户端发起的请求会直接到达服务器,
使用no-cache指令的目的是为了防止从缓存中返回过期的资源
可以使用no-cache标头代表不缓存过期资源。
no-cache属于Cache-Control通用标头
no-cache很容易和no-store混淆
一般都会把no-cache认为是不缓存, 其实不是这样。
no-cache示意图
no-cache示意图
其一般的表示方法如下
Cache-Control:no-cache
也可以使用max-age=0来实现不缓存的效果。
Cache-Control:max-age=0
举个例子
No-Cache就相当于是吃着碗里的, 占着锅里的,
如果锅里还有新的肉片, 就先吃锅里的,如果锅里没有新的,再吃自己的,
这里锅里的就相当于是源服务器产生的,碗里的就相当于是缓存的。
真正意义上的不缓存no-store
no-store才是真正意义上的不缓存,
每次服务器接受到客户端的请求后, 都会返回最新的资源给客户端。
Cache-Control:no-store
public属性只出现在客户端响应中, 表示响应可以披任何缓存所缓存。
共享缓存 Public Cache
共享缓存 Public Cache
共享缓存是一种用于存储要由多个用户重用的响应缓存。
public属性只出现在客户端响应中, 表示响应可以被任何缓存所缓存。
共享缓存是一种缓存,它可以存储多个用户重复使用的请求/响应。
共享缓存一般使用public来表示,
它的一般表示方法如下
Cache-Control:public
共享缓存示意图
共享缓存示意图
私有缓存Private Cache
可以使用private来实现私有缓存,
私有缓存也称为专用缓存,它只适用于单个用户
当指定private指令后, 响应只以特定的用户作为对象
这与public的用法相反, 缓存服务器只对特定的客户端进行缓存,其他客户端发送过来的请求,缓存服务器则不会返回缓存。
私有缓存只用来缓存单个用户,你可能在浏览器设置中看到了缓存,浏览器缓存包含服务器通过HTTP下载下来的所有文档。
这个高速缓存用于使访问的文档可以进行前进/后退, 保存操作而无需重新发送请求到源服务器。
它的一般表示方法如下
Cache-Control:private
私有缓存示意图
私有缓存示意图
(2)缓存有效性时间(闳值性)
max-age
max-age可以用在请求或者响应中,
当客户端发送带有max-age的指令时, 缓存服务器会判断自己缓存时间的数值和max-age的大小
如果比max-age小, 那么缓存有效, 可以继续给客户端返回缓存的数据
如果比max-age大, 那么缓存服务器将不能返回给客户端缓存的数据。
Cache-Control:max-age-60
Cache-Control:max-age-0
注意:这个max-age的值是相对于请求时间的
如果max-age=0, 那么缓存服务器将会直接把请求转发到服务器
s-maxage
smx age指令的功能和max-age指令的功能相同
不同点之处在于s-maxage不能用于私有缓存,只能用于多用户使用的公共服务器,
对于同一用户的重复请求和响应来说,这个指令没有任何作用。
Cache-Control:s-maxage=68
max-stale
max-stable只能出现在请求中, 表示客户端会接受缓存数据, 即使过期也照常接收。
Cache-Control:max-stable=60
min-fresh
min-fresh只能出现在请求中, min-fresh要求缓存服务器返回min-fresh时间内的缓存数据。
例如Cache-Control:min-fresh=60,这就要求缓存服务器发送60秒内的数据。
Cache-Control:min-fresh=60
(3)重新验证并重新加载
must-revalidate
表示一旦资源过期,缓存就必须在原始服务器上没有成功验证的情况下才使用其过期的数据. |
Cache-Control:must-revalidate
proxy-revalidate
proxy-revalidate指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前, 必须再次验证缓存的有效性
Cache-Control:proxy-revalidate
(4)其他特性
only-if-cached
这个标头只能出现在请求中
使用only-if-cached指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。
Cache-Control:only-if-cached
no-transform
使用no-transform指令规定无论是在请求还是响应中, 缓存都不能改变实体主体的媒体类型,
Cache-Control:no-transform
说明
no-store、no_cache、must-revalidate和max-age可以一起看,
下面是一个这四个标头的流程图(缓存控制流程图)
(缓存控制流程图)
Connection
HTTP协议使用TCP来管理连接方式
Connection决定当前事务(一次三次握手和四次挥手) 完成后, 是否会关闭网络连接。
逐跳首部、连接的管理
主要有两种连接方式
持久性连接
持久性连接指的是一次会话完成后, TCP连接并未关闭, 第二次再次发送请求后, 就不再需要建立TCP连接, 而是可以直接进行请求和响应。
即一次事务完成后,不关闭网络连接
它的一般表示形式如下
Connection; keep-alive
从HTTP 1.1开始, 默认使用持久性连接。
keep-alive也是一个通用标头, 一般Connection都会和keep-alive一起使用,
它们的主要表现形式如下
Connection:Keep-Alive
Keep-Alive:timeout=5, max= 1050
Keep-Alive:timeout=5, max= 1050
keep-alive有两个参数
timeout
指的是空闲连接必须打开的最短时间
也就是说这次请求的连接时间不能少于5秒
max
指的是在连接关闭之前,服务器所能够收到的最大请求数
非持久性连接
非持久性连接表示一次会话请求/响应后关闭连接的方式。
即一次事务完成后关闭网络连接
它的一般表示形式如下
Connection:close
HTTP 1.1之前使用的连接都是非持久连接
Date
Date是一个通用标头, 它可以出现在请求标头和响应标头中
创建报文的日期时间
它的基本表示如下
Date:Wed, 210ct 201507:28:00GMT
表示的是格林威治标准时间
这个时间要比北京时间慢八个小时 (图解为对应的时区换算)
时区换算
Pragma(遗留字段)
Pragma是http 1.1之前版本的历史遗留字段, 仅作为与http的向后兼容而定义。
报文指令
它的一般形式如下
Pragma:no-cache
只用于客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源,
如果所有的中间服务器都以实现HTTP/1.1为标准, 那么直接使用Cache-Control:no-cache即可
如果不是的话,就要包含两个字段,如下
Cache-Control:no-coche
Pragma:no-cache
Pragma:no-cache
Trailer
首部字段Trailer会事先说明在报文主体后记录了哪些首部字段。
报文末端的首部一览
该首部字段可应用在HTTP/1.1版本分块传输编码时
一般用法如下
Transfer-Encoding:chunked
Trailer:Expires
Trailer:Expires
以上用例中, 指定首部字段Trailer的值为Expires, 在报文主体之后(分块长度0之后) 出现了首部字段Expires.
Transfer-Encoding
Transfer-Encoding属于内容协商的范畴
规定了传输报文主体时采用的编码方式
首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。
作用:指定报文主体的传输编码方式,规定了传输报文所采用的编码方式
HTTP/1.1的传输编码方式仅对分块传输编码有效。
注意:HTTP 1.1的传输编码方式仅对分块传输有效
但是HTTP 2.0就不再支持分块传输, 而提供了自己更有效的数据传输机制。
Transfer-Encoding:chunked
Transfer-Encoding也属于Hop-by-hop(逐跳) 首部
回顾HTTP报文标头
根据属性所在的位置分为
通用标头
请求标头
响应标头
实体标头
按照是否被缓存分为
端到端首部(End-to-End)
逐跳首部(Top-to-Top)
除了下面八种属于逐跳首部外,其余都属于端到端首部
Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization、
Trailer
TE
Transfer-Encoding
Upgrade
Transfer-Encoding用于两个节点之间传输消息, 而不是资源本身。
在多个节点传输消息的过程中, 每一段消息的传输都可以使用不同的Transfer-Encoding.
如图所示
每一段消息的传输都可以使用不同的Transfer-Encoding
Transfer-Encoding支持文件压缩
如果想要以文件压缩后的形式发送,Transfer-Encoding所有可选类型如下
chunked
chunked:数据按照一系列块发送
在这种情况下, 将省略Content-Length标头, 井在每个块的开头,需要以十六进制填充当前块的长度,后跟'\r\n',然后是块本身,然后是另一个*Xr\n',
当将大量数据发送到客户端并且在请求已被完全处理之前,可能无法知道响应的总大小时, 分块编码很有用。
终止块通常是0。累随Transfer-Encoding后面的是Trailer标头, Trailer可能为空。
例如, 在生成由数据库查询产生的大型HTML表时或在传输大型图像时。
分块的响应看起来像这样
子主题
compress
使用Lempel-Ziv-Welch(LZW) 算法的格式, 值名称取自UNIX压缩程序, 该程序实现了该算法。
现在几乎没有浏览器使用这种内容编码了,因为这个专利在2003年就停掉了
deflate
使用zlib(在RFC 1950定义) 结构和deflate压缩算法
gzip
使用Lempel-Ziv编码(LZ 77) 和32位CRC的格式。
这最初是UNIX gzip程序的格式, HTTP/1.1标准还建议出于兼容性目的, 支持此内容编码的服务器应将x-gzip识别为别名。
identity
使用身份功能(即无压缩或修改) 。
也可以列出多个值,以逗号分隔,类似一个集合列表
Transfer-Encoding:gzip, chunked
Upgrade
首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,
其参数值可以用来指定一个完全不同的通信协议。
升级为其他协议
Upgrade
上图用例中, 首部字段Upgrade指定的值为TLS/1.0.请注意此处两个字段首部字段的对应关系,
Connection的值被指定为Upgrade, Upgrade首部字段产生作用的对象仅限于客户端和临近服务器之间。
Connection的值被指定为Upgrade, Upgrade首部字段产生作用的对象仅限于客户端和临近服务器之间。
因此, 使用首部字段Upgrade时, 还需要额外指定Connection:Upgrade.
对于附有首部字段Upgrade的请求, 服务器可用1015 witching Protocols状态码作为响应返回.
Via
使用Via是为了跟踪客户端和服务器之间的请求/响应路径, 避免请求循环以及能够识别请求/响应链
中发送者协议的功能.
中发送者协议的功能.
代理服务器的相关信息
Via字段由代理服务器添加, 不论是正向代理还是反向代理, 并且可以出现在请
求标头和响应标头中,它用于跟踪消息转发。
求标头和响应标头中,它用于跟踪消息转发。
例如下图所示
子主题
Via后面的的1.1, 1.0表示接收服务器上的HTTP版本, Via首部是为了跟踪路径, 经常和TRACE方法一起使用。
Warning(即将被弃用)
注意:Warning字段即将被弃用
错误通知
查阅Warning(https://github.com/httpwg/http-core/issues/139)andWaming:header&
stale-while-revalidate(https://github.com/whatwg/fetch/issues/913) 获取更多细节
stale-while-revalidate(https://github.com/whatwg/fetch/issues/913) 获取更多细节
Warning通用HTTP标头通常会告知用户一些与缓存相关的问题的警告
HTTP/1.1中定义了7种警告
110Response is stale(响应已过期)
代理返回已过期的资源
111Revalidation failed(再验证失败)
代理再验证资源有效性时失败(服务器无法到达等原因)
112Disconnection operation(断开连接操作)
代理与互联网连接被故意切断
113Heuristic exparation(试探性过期)
响应的使用期超过24小时(有效缓存的设定时间大于24小时的情况下)
199Miscellaneous warning(杂项警告)
任意的警告内容
214Transformation applied(使用了转换)
代理对内容编码或媒体类型等执行了某些处理时
299Miscellaneous persistent warning(持久杂项警告)
任意的警告内容
图解HTTP/1.1中定义了7种警告
图解HTTP/1.1中定义了7种警告
请求标头
请求标头用于客户端发送HTTP请求到服务器中所使用的字段,
下面一起来看一下HTTP请求标头都包含脚些字段,分别是什么意思,下面会介绍
常用的请求标头
Accept(内容协商标头)
HTTP请求标头会告知客户端能够接收的MIME类型是什么
用户代理可处理的媒体类型
接受请求HTTP标头会通告客户端其能够理解的MIME类型
什么是MIME ?
MIME:MIME(MultipurposeInternetMailExtensions)
是描述消息内容类型的因特网标准,
MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
什么是MIME类型呢?
MIME类型其实就是一系列消息内容类型的集合
那么MIME类型都有哪些呢?
文本文件:text/html、text/plain、text/css、application/xhtml+xml、application/xml
图片文件:image/peg, image/gif、image/png
视频文件:video/mpeg、video/quicktime
应用程序二进制文件:application/octet-stream、application/zip
比如, 如果浏览器不支持PNG图片的显示, 那Accept就不指定image/png, 而指定可处理的image/gif和image/jpeg等图片类型。
一般MIME类型也会和q这个属性一起使用
q表示的是权重, 来看一个例子
q是什么?q表示的是权重, 来看一个例子
这是什么意思呢?若想要给显示的媒体类型增加优先级,则使用q=来额外表示权重值,
没有显示权重时,默认值是1.0
没有显示权重时,默认值是1.0
也就是说, 这是一个放置顺序, 权重高的在前, 低的在后, application/xml; q=0.9是不可分割的整体。
Accept-Charset(内容协商标头)
Accept-Charset表示客户端能够接受的字符编码。
优先的字符集
规定服务器处理表单数据所接受的字符集。
Accept-charset属性规定服务器处理表单数据所接受的字符编码
Accept-charset属性允许你指定一系列字符集,服务器必须支持这些字符集,从而得以正确解释表单中的数据。
Accept-Charset也是属于内容协商的一部分
Accept-Charset没有对应的标头, 服务器会把这个值放在Content-Type中用charset=xxx来表示
它和Accept一样, 也可以用q来表示字符集, 用退号进行分割
例如
Accept-Charset
例如, 浏览器请求GBK或UTF-8的字符集, 然后服务器返回的是UTF-8编码,
就是下面这样
Accept-Charset:gbk, utf-8
Content-Type:text/htmL;charset-utf-8
Content-Type:text/htmL;charset-utf-8
事实上, 很多以Accept-*开头的标头, 都是属于内容协商的范畴, 关于内容协商我们下面会说。
常用的字符集
UTF-8-Unicode字符编码
ISO-8859-1-拉丁字母表的字符编码
Accept-Encoding(内容协商标头)
优先的内容编码
表示HTTP标头会标明客户端希望服务端返回的内容编码, 这通常是一种压缩算法, Accept-Encoding
也是属于内容协商的一部分, 使用并通过客户端选择Content-Encoding内容进行返回。
也是属于内容协商的一部分, 使用并通过客户端选择Content-Encoding内容进行返回。
即使客户端和服务器都能够支持相同的压缩算法,服务器也可能选择不压缩井返回,这种情况可能是由
于这两种情况造成的:
于这两种情况造成的:
要发送的数据已经被压缩了一次,第二次压缩并不会导致发送的数据更小
服务器过载, 无法承受压缩带来的性能开销, 通常, 如果服务器使用CPU超过80%,Microsoft则建议不要使用压缩
下面是Accept-Encoding的使用方式
Accept-Encoding:gzip
由文件压缩程序gzip生成的编码格式, 使用Lempel-Ziv编码(LZ 77) 和32位CRC的压缩格式,
感兴趣的同学可以读一下(https://en.wikipedia.org/wiki/LZ77andLZ78#LZ77)
Accept-Encoding:compress
使用Lempel-Ziv-Welch(LZW) 算法的压缩格式,
有兴趣的同学可以读(https://en.wikipedia.org/wiki/LZW)
Accept-Encoding:deflate
使用zlib结构和deflate压缩算法的压缩格式,
参考(https://en.wikipedia.org/wiki/Zlib) 和(https://en.wikipedia.org/wiki/DEFLATE)
Accept-Encoding:br
使用Brot i算法的压缩格式
参考(https://en.wikipedia.org/wiki/Brotli)
不执行压缩或不会变化的默认编码格式
Accept-Encoding:identity
Accept-Encoding:*
*:匹配标头中未列出的任何内容缩码,
如果没有列出Accept-Encoding, 这就是默认值
并不意味着支持任何算法,只是表示没有偏好
Accept-Encoding:deflate, gzip; q=1.0, *; q=0.5
;q-采用权重q值来表示相对优先级, 这点与首部字段Accept相同
上面的几种表述方式就已经把Accept-Encoding的属性列全了
Accept-Language(内容协商标头)
优先的语言(自然语言)
首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集(指中文或英文等) , 以及自然语言集的相对优先级。
Accept-Language请求表示客户端需要服务端返回的语言类型,
Accept-Language也属于内容协商的范畴。
服务端通过Content-Language进行响应,
和Accept首部字段一样, 按权重值q=来表示相对优先级。
可一次指定多种自然语言集。
例如
Accept-Language:de
Accept-Language:de-CH
AcceptLanguage:en-US,en;q=0.5
Accept-Language:de-CH
AcceptLanguage:en-US,en;q=0.5
Authorization
Web认证信息
HTTP Authorization请求头用于向服务器认证用户代理的凭据,
通常用在服务器以401未经授权状态和WWW-Authenticate标头响应之后,
啥意思呢?你不明白的话我画张图给你看
子主题
请求标头Authorization是用来告知服务器, 用户的认证信息,
服务器在只有收到认证后,才会返回给客户端200OK的响应,
如果没有认证信息,则会返回401并告知客户端需要认证信息,
详细关于Authorization的信息, 后面也会详细解释
Expect
期待服务器的特定行为
Expect HTTP请求标头指示服务器需要满足的期望才能正确处理请求。
如果服务器没有办法完成客服端所期望完成的事情井且服务端存在错误的话, 会返回417 Expectation Failed.
HTTP 1.1只规定了100-continue.
如果服务器能正常完成客户端所期望的事情,会返回100
如果不能满足期望或返回任何其他4xx的状态码,会返回417
例如
例如
From
用户的电子邮件地址
From请求头用来告知服务器使用用户代理的电子邮件地址,
通常情况下, 其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。
在使用代理的情况下, 应尽可能包含From首部字段。
例如
From:webmaster@example.org
你不应该将From用在访问控制或者身份验证中
Host
请求资源所在服务器
Host请求头指明了服务器的域名(对于虚拟主机来说) , 以及(可选的) 服务器监听的TCP端口号。
如果没有给定端口号, 会自动使用被请求服务的默认端口(比如请求一个HTTP的URL会自动使用80作为端口)。
Host:developer.mozilla.org
Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段
五大条件请求标头
If-Match
比较实体标记(ETag)
If-Match后面可以跟一大堆属性, 形式像If-Match这种的请求头称为条件请求,
服务器接收到条件请求后,需要判定条件请求是否满足,只有条件请求为真,才会执行条件请求
类似的还有If-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since
对于GET和POST方法, 服务器仅在与列出的ETag(响应标头)之一匹配时才返回请求的资源。
这里又多了一个新词ETag, 我们稍后再说ETag的用法。
对于像是PUT和其他非安全的方法, 在这种情况下,它仅仅将上传资源。
下面是两种常见的案例
对于GET和POST方法, 会结合使用Range标头, 它可以确保新发送请求的范围与上一个
请求的资源相同,如果不匹配的话,会返回416响应。
请求的资源相同,如果不匹配的话,会返回416响应。
对于其他方法, 特别是PUT方法, If-Match可以防止丢失更新, 服务器会比对If-Match的
字段值和资源的ETag值, 仅当两者一致时, 才会执行请求。反之, 则返回状态码412
Precondition Failed的响应
字段值和资源的ETag值, 仅当两者一致时, 才会执行请求。反之, 则返回状态码412
Precondition Failed的响应
例如
If-Match:"bfc13a64729c 4298 ef5b2c2730249c88ca92d82d"
If-Match: *
If-Match: *
If-None-Match
比较实体标记(与If-Match相反)
HTTP请求标头使请求成为条件请求
条件请求, 它与If-Match的作用相反, 仅当If-None-Match的字段值与ETag值不一致时,可处理该请求
对于GET和HEAD, 仅当服务器没有与给定资源匹配的ETag时, 服务器将返回200作为响应
对于其他方法, 仅当最终现有资源的ETag与列出的任何值都不匹配时, 才会处理请求
当GET和POST发送的If-None-Match与ETag匹配时, 服务器会返回304。
If-None-Match:“bfc13a64729c4290 ef5b2c2730249c88ca92d82d"
If-None-Match:W/"67ob43","54ed21","7892dd"
If-None-Match:*
If-None-Match:W/"67ob43","54ed21","7892dd"
If-None-Match:*
子主题
有同学可能会好奇W/是什么意思, 这其实是ETag的弱匹配, 关于ETag,会在响应标头中详细讲述。
If-Modified-Since
比较资源的更新时间
If-Modified-Since是HTTP条件请求的一部分
If-Modified-Since与If-None-Match结合使用时, 它将被忽略, 除非服务器不支持If-None-Match。
lf-Modified-Since只能使用GET和HEAD请求。
If-Modified-Since用于确认代理或客户端拥有的本地资源的有效性。
获取资源的更新日期时间, 可通过确认首部字段Last-Modified来确定。
只有在给定日期之后, 服务端修改了请求所需要的资源,才会返回200OK的响应。
如果在Last-Modified之后更新了服务器资源, 那么服务器会响应200
如果在给定日期之后,服务端没有修改内容,响应会返回304并且不带任何响应体。
如果在Last-Modified之后没有更新过资源, 则返回304。
一般表示如下
If-Modified-Since:Wed, 21 Oct 2015 07:28:00 GMT
一般表示如下
注意:这是格林威治标准时间。HTTP日期始终以格林尼治标准时间表示, 而不是本地时间。
If-Unmodified-Since
If-Unmodified-Since HTTP请求标头也是一个条件请求,
比较资源的更新时间(与If-Modifed-Since相反)
服务器只有在给定日期之后没有对其进行修改时,服务器才返回请求资源。
如果在指定日期时间后发生了更新,则以状态码412Precondition Failed作为响应返回。
If-Unmodified-Since:Wed, 210ct 201507:28:00GMT
If-Range
If-Range也是条件请求,
资源未更新时,发送实体Byte的范围请求
如果满足条件(Hf-Range的值和ETag值或者更新的日期时间一致) , 则会发出范围请求,否则将会返回全部资源,
它的一般表示如下
If-Range:Wed, 210ct 201507:28:00GMT
Max-Forwards
最大传输逐跳数
MDN把这个标头置灰了, 所以下面内容取自《图解HTTP》
Max-Forwards一般用于TRACE和OPTION方法,
发送包含Max-Forwards的首部字段时, 每经过一个服务器, Max-Forwards的值就会-1,直到Max-Forwards为0时返回
Max-Forwards是一个十进制的整数值。
Max-Forwards: 18
可以灵活使用首部字段Max-Forwards, 针对以上问题产生的原因展开调查。
由于当Max-Forwards字段值为0时,服务器就会立即返回响应,
由此我们至少可以对以那台服务器为终点的传输路径的通信状况有所把握。
Proxy-Authorization(代理认证)
代理服务器要求客户端的认证信息
Proxy-Authorization是属于请求与认证的范畴, 在上面提到一个认证的HTTP标头是Authorization,
这个HTTP请求标头和Proxy-Authenticate拼接很相似, 但是概念不同
这个标头用于向代理服务器提供凭据
不同于Authorization发生在客户端-服务器之间:Proxy-Authorization发生在代理服务器和客户端之间。
它表示接收到从代理服务器发来的认证时, 客户端会发送包含首部字段Proxy-Authorization的请求, 以告知服务器认证所需要的信息。
Proxy-Authorization:Basic YWxhZGRpbjpvcGVuc2VzYW1L
Range
实体的字节范围请求
Range HTTP请求标头指示服务器应返回文档指定部分的资源, 可以一次请求一个Range来返回多个
部分,服务器会将这些资源返回各个文档中。
部分,服务器会将这些资源返回各个文档中。
如果服务器成功返回,那么将返回206响应;
如果Range范围无效, 服务器返回416 Range Not Satisfiable错误;
服务器还可以忽略Range标头,并且返回200作为响应。
如果Range范围无效, 服务器返回416 Range Not Satisfiable错误;
服务器还可以忽略Range标头,并且返回200作为响应。
Range:bytes=208-1000,2000-6576,19800-
Referer
对请求中URI的原始获取方
TTP Referer属性是请求标头的一部分
当浏览器向web服务器发送请求时, 一般会带上Referer, 告诉服务器该网页是从哪个页面链接过来的, 服务器因此可以获得一些信息用于处理。
Referer:https://developer.mozilla.org/testpage.html
TE
传输编码的优先级
首部字段TE会告知服务器客户端能够处理响应的传输编码方式及相对优先级。
它和首部字段Accept Encoding的功能很相像, 但是用于传输编码.
TE:gzip, deflate; q=0.5
首部字段TE除指定传输编码之外, 还可以指定伴随traller字段的分块传输编码的方式, 应用后者时,
只需把trailers赋值给该字段值。
只需把trailers赋值给该字段值。
TE:trailers, deflate; q=0.5
User-Agent
HTTP客户端程序的信息
首部字段User-Agent会将创建代理的浏览器和用户代理名称等信息传达给服务器
Mozilla/5.0(WindowsNT 6.1; Win 64; x64; rv47.0) Gecko/ 20100101 Firefox /47.0
响应标头
刚刚着重点一直放在客户端请求,现在把关注点转换一下放在服务器上。
响应首部字段是由服务器发送给客户端响应中所包含的字段,用于补充相应信息等,
这部分标头也是非常多,我们先一起来看一下
常用的响应标头
Accept-Ranges
是否接受字节范围请求
Accept-Ranges HTTP响应标头, 这个标头有两个值
Accept-Ranges:bytes
当服务器能够处理客户端发送过来的请求时, 使用bytes来指定
Accept-Ranges:none
当服务器不能处理客户端发来的请求时, 使用none来指定
Age
推算资源创建经过时间
Age HTTP响应标头告诉客户端源服务器在多久之前创建了响应, 它的单位为秒,
Age标头通常接近于0
如果是0则可能是从源服务器获取的
如果不是0表示可能是由代理服务器创建, 那么Age的值表示的是缓存后的响应再次发起认证到认证完成的时间值。
代理创建响应时必须加上首部字段Age.
一般表示如下
Age: 24
ETag
令客户端重定向至指定URI
ETag对于条件请求来说真是太重要了。
因为条件请求就是根据ETag的值进行匹配的, 下面我们就来详细了解一下。
ETag介绍
ETag响应头是特定版本的标识,
它能够使缓存变得更高效并能够节省带宽
因为如果缓存内容未发生变更, Web服务器则不需要重新发送完整的响应。
除此之外, ETag能够防止资源同时更新互相覆盖。
ETag资源更新图解
ETag资源更新图解
如果给定URL上的资源发生变更, 必须生成一个新的ETag值, 通过比较它们可以确定资源的两个表示形式是否相同。
ETag值有两种
强ETag值
无论实体发生多么细微的变化都会改变其值
一般的表示如下
ETag:"33a64df551425fc c55e4d42a148795d9f25f89d 4”
弱ETag值
弱ETag值只用于提示资源是否相同。
只有资源发生了根本改变, 产生差异时才会改变ETag值
这时, 会在字段值最开始处附加W/
一般的表示如下
ETag:W/0815"
ETag:W/0815"
Location
令客户端重定向至指定URI
Location响应标头表示URL需要重定向页面, 它仅仅与3xx(重定向) 或201(已创建) 状态响应一起使用。
下面是一个页面重定向的过程
页面重定向的过程
使用首部字段Location可以将响应接受方引导至某个与请求URI位置不同的资源。
Location和content-Location是不一样的
Location表示目标的重定向(或新创建资源的URL) .然而Content-Location表示发生内容协商时用于访问资源的直接URL, 而无须进一步协商。
Location是与响应相关联的标头, 而Content-Location与返回的实体相关联。
Location
Proxy-Authenticate(代理认证)
代理服务器对客户端的认证信息
HTTP响应标头Proxy-Authenticate会定义认证方法, 应该使用身份验证方法来访问代理服务器后面的资源,即客户端。
它与HTTP客户端和服务端之间的访问认证行为相似, 不同之处在于Proxy-Authenticate的认证双方是客户端与代理之间
它将请求认证到代理服务器,从而允许它进一步发送请求。
Proxy-Authenticate:Basic
Proxy-Authenticate:Basic realm="Access to the internal site"
Proxy-Authenticate:Basic realm="Access to the internal site"
Retry-After
对再次发起请求的时机要求
HTTP响应标头Retry-After告知客户端需要在多久之后重新发送请求,
使用此标头主要有如下三种情况
当发送503(服务不可用)响应时,这表示该服务预计无法使用多长时间。
当发送429(太多请求)响应时,这表示发出新请求之前要等待多长时间,
当发送重定向的响应像是301(永久移动),这表示在发出重定向请求之前要求用户客户端等待的最短时间
字段值可以指定为具体的日期时间,也可以是创建响应后所持续的秒数
例如
Retry-After:Wed, 210ct 201507:28:00GMT
Retry-After:128
Retry-After:Wed, 210ct 201507:28:00GMT
Retry-After:128
Server
HTTP服务器的安装信息
服务器标头包含有关原始服务器用来处理请求的软件的信息。
应该避免使用过于冗长和详细的Server值, 因为它们可能会泄露内部实施细节, 这可能会使攻击者容易地发现并利用已知的安全漏洞。
例如下面这种写法 Server:Apache/2.4.1(Unix)
Vary
代理服务器缓存的管理信息
Vary HTTP响应标头
确定如何匹配请求标头, 以决定是否可以使用缓存的响应, 而不是从原始服务器请求一个新的响应。
Vary:User-Agent
www-Authenticate
服务器对客户端的认证信息
HTTP WW-Authenticate响应标头定义了应用于获得对资源的访问权限的身份验证方法。
WWW-Authenticate标头与401未经授权的响应一起发送。
它的一般表示形式如下
WAW-Authenticate:Basic
WAW-Authenticate:Basicredlm-"Accesstothestagingsite", charset-"UTF-8"
WAW-Authenticate:Basicredlm-"Accesstothestagingsite", charset-"UTF-8"
Access-Control-Allow-Origin
Access-Control-Allow-Origin
一个返回的HTTP标头可能会具有Access-Control-Allow-Origin
Access-Control-Allow-Origin指定一个来源, 它告诉浏览器允许该来源进行资源访问,
否则-对于没有凭据的请求*通配符,告诉浏览器允许任何源访问资源。
例如,要允许源https://mozilla.org的代码访问资源,可以指定:
Access-Control-Allow-Origin:https://mozilla.org
Vary:Origin
Access-Control-Allow-Origin:https://mozilla.org
Vary:Origin
如果服务器指定单个来源而不是*通配符的话, 则服务器还应在Vary晌应标头中包含Origin,
以向客户端指示服务器响应将根据原始请求标头的值而有所不同。
以向客户端指示服务器响应将根据原始请求标头的值而有所不同。
Cache-Control
Cache-Control是一个通用标头, 他可以出现在请求标头和响应标头中
详细见请求标头中
Cache-Control的种类比较多,虽然说这是一个通用标头,但是又一些特性是请求标头具有的,有一些是响应标头才有的。<br>
Keep-Alive
Keep-Alive表示的是Connection非持续连接的存活时间, 可以进行指定。
持久性连接
持久性连接指的是一次会话完成后, TCP连接并未关闭, 第二次再次发送请求后, 就不再需要建立TCP连接, 而是可以直接进行请求和响应。
即一次事务完成后,不关闭网络连接
它的一般表示形式如下
Connection; keep-alive
从HTTP 1.1开始, 默认使用持久性连接。
keep-alive也是一个通用标头, 一般Connection都会和keep-alive一起使用,
它们的主要表现形式如下
Connection:Keep-Alive
Keep-Alive:timeout=5, max= 1050
Keep-Alive:timeout=5, max= 1050
keep-alive有两个参数
timeout
指的是空闲连接必须打开的最短时间
也就是说这次请求的连接时间不能少于5秒
max
指的是在连接关闭之前,服务器所能够收到的最大请求数
Set-Cookie
Set-Cookie用于服务器向客户端发送sessionID.
X-Frame-Options
HTTP首部字段是可以自行扩展的。所以在Web服务器和浏览器的应用上, 会出现各种非标准的首部字段。
首部字段X-Frame-Options属于HTTP响应首部, 用于控制网站内容在其他Web网站的Frame标签内的显示问题。
其主要目的是为了防止点击劫持(click jacking) 攻击。
实体标头
实体标头用于HTTP请求和响应中, 例如Content-Length, Content-Language, Content-Encoding的标头是实体标头。
实体标头是描述消息正文内容的HTTP标头, 实体标头用于HTTP请求和响应中。
实体标头不局限于请求标头或者响应标头
下面例子中, Content-Length是一个实体标头,但是却出现在了请求报文中
常用的实体标头
Allow
HTTP实体标头Allow列出了资源支持的方法集合。
资源可支持的HTTP方法
如果服务器响应405 Method Not Allowed状态码以指示可以使用哪些请求方法,则必须发送此标头。
例如
Allow:GET, POST, HEAD
这段代码表示服务器允许支持GET、POST和HEAD方法。
当服务器接收到不支持的HTTP方法时, 会以状态码405 Method Not Allowed作为响应返回。
Content-Encoding(内容协商标头)
上面讲过Accept Encoding是客户端希望服务端返回的内容编码, 但是实际上服务端返回给客
户端的内容编码实际上是通过Content-Encoding返回的。
户端的内容编码实际上是通过Content-Encoding返回的。
实体主体适用的编码方式
这又是一个比较麻烦的属性, 这个实体报头用来压缩媒体类型。
Content-Encoding指示对实体应用了何种编码。
Content-Encoding实体标头用于压缩媒体类型,
它让客户端知道如何进行解码操作, 从而使客户端获得Content-Type标头引用的MIME类型。
内容编码是指在不丢失实体信息的前提下所进行的压缩。
这个属性可以应用在请求报文和响应报文中
主要也是四种, 和Accept-Encoding相同, 它们是
gzip
compress
deflate
identity
下面是一组请求/响应内容压缩编码
Accept-Encoding:gzip,deflate
Content-Encoding:gzip
Content-Encoding:gzip
下面是一组请求/响应内容压缩编码
表示如下
Content-Encoding:gzip
Content-Encoding:compress
Content-Encoding:deflate
Content-Encoding:identity
Content-Encoding:br
Content-Encoding:gzip, identity
Content-Encoding:deflate, gzip
Content-Encoding:compress
Content-Encoding:deflate
Content-Encoding:identity
Content-Encoding:br
Content-Encoding:gzip, identity
Content-Encoding:deflate, gzip
Content-Language(内容协商标头)
首部字段Content-Language会告知客户端, 服务器使用的自然语言是什么,
实体主体的自然语言
实体报头描述了客户端或者服务端能够接受的语言。
它与Accept-Language相对,下面是一组请求/响应使用的语言类型
例如
Content-Language:de-DE
Content-Language:en-US
Content-Languoge:de-DE,en-CA
Content-Language:en-US
Content-Languoge:de-DE,en-CA
Content-Language实体标头用于描述面向受众的语言, 以便使用户根据用户自己的首选语言进行区分
Content-Type(内容协商标头)
HTTP响应标头Content-Type说明了实体内对象的媒体类型,
和首部字段Accept一样使用, 表示服务器能够响应的媒体类型。
Content-Type实体标头,用于指示资源的MIME类型。
实体主体的媒体类型
作为响应, Content-Type标头告诉客户端返回的内容的内容类型实际上是什么。
Content-type有两种值:MIME类型和字符集编码,
例如Content-Type:text/html;charset-UTF-8
在某些情况下, 浏览器将执行MIME嗅探, 并且不一定遵循此标头的值:为防止此行为, 可以将标头X-Content-Type-Options设置为no sniff,
Content-Length
Content-Length的实体标头,指服务器发送给客户端的实际主体大小, 以字节为单位。
实体主体的大小(单位:字节)
实体报头指示实体主体的大小, 以字节为单位, 发送到接收方
Content-Length:3000
如上,服务器返回给客户端的主体大小是3000字节。
Content-Location
Content-Location可不是对应Accept-Location, 因为没有这个标头哈哈哈哈。
实际上Content-Location对应的是Location.Location和Content-Location是不一样的,
Location表示重定向的URL, 而Content-Location表示用于访问资源的直接URL,
替代对应资源的URI
以后无需进行进一步的内容协商, Location是与响应关联的标头, 而Content-Location是与返回的数据相关联的标头,
如果你不好理解, 看一下下面的表格
如果你不好理解, 看一下下面的表格
Content-MD5
客户端会对接收的报文主体执行相同的MD5算法, 然后与首部字段Content-MD5的字段进行比较。
实体主体的报文摘要
Content-MD5:e10adc3949ba59abbe56e057f20f883e
首部字段Content-MD5是一串由MD5算法生成的值,
其目的在于检查报文主体在传输过程中是否保持完整,有无被修改的情况,以及确认传输到达。
图解Content-MD5
图解Content-MD5
Content-Range
HTTP的Content-Range响应标头是针对范围请求而设定的,
实体主体的位置范围
返回响应时使用首部字段Content-Range, 能够告知客户端响应实体的哪部分是符合客户端请求的, 字段以字节为单位。
它的一般表示如下
Content-Range:bytes200-1000/67589
上段代码表示从所有67589个字节中返回200-1000个字节的内容
Expires
HTTP Expires实体标头包含日期/时间,
实体主体过期的日期时间
在该日期/时间之后, 响应被认为过期;
在响应时间之内, 响应被认为有效。
特殊的值比如0表示过去的日期,表示资源已过期。
Expires:Wed, 210ct 201507:28:00GMT
源服务器会将资源失效的日期或时间发送给客户端, 缓存服务器在接受到Expires的响应后, 会判断是否把缓存返回给客户端。
源服务器不希望缓存服务器对资源缓存时, 最好在Expires字段内写入与首部字段Date相同的时间值。
但是, 当首部字段Cache-Control有指定max-age指令时, 比起首部字段Expires, 会优先处理max-age指令。
Last-Modified
资源的最后修改日期时间
实体字段Last-Modified指明资源的最后修改时间, 它用作验证器来确定接收或存储的资源是否相同。
它的作用不如ETag那么准确, 它可以作为一种后备机制, 包含If-Modified-Since或If-Unmodified-Since标头的条件请求将使用此字段。
它的一般表示如下
Last-Modified:Wed, 210ct 201507:28:00CMT
HTTP内容协商
什么是内容协商
在HTTP中,内容协商是一种用于在同一URL上提供资源的不同表示形式的机制。
内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为适合的资源。
内容协商会以响应资源的语言、字符集、编码方式等作为判断的标准
内容协商功能图
内容协商功能图
内容协商的种类
服务器驱动协商(Server-driven Negotiation)
这种协商方式是由服务器端进行内容协商。
服务器端会根据请求首部字段进行自动处理
客户端驱动协商(Agent-driven Negotiation)
这种协商方式是由客户端来进行内容协商。
透明协商(Transparent Negotiation)
是服务器驱动和客户端驱动的结合体
是由服务器端和客户端各自进行内容协商的一种方法。
内容协商的分类
内容协商的分类有很多种,
主要的几种类型是Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Language。
一般来说, 客户端用Accept头告诉服务器希望接收什么样的数据, 而服务器用Content头告诉客户端实际发送了什么样的数据。
为什么需要内容协商 ?
为什么需要内容协商呢?在回答这个问题前,先来看一下TCP和HTTP的不同。
TCP协议
在TCP/IP协议栈里, 传输数据基本上都是header+body的格式。
但TCP、UDP因为是传输层的协议,
它们不会关心body数据是什么, 只要把数据发送到对方就算是完成了任务。
HTTP协议
而HTTP协议则不同, 它是应用层的协议
数据到达之后需要告诉应用程序这是什么数据。
当然不告诉应用这是哪种类型的数据,应用也可以通过不断尝试来判断,
但这种方式无疑十分低效,而且有很大几率会检查不出来文件类型,
所以鉴于此,浏览器和服务器需要就数据的传输达成一致
浏览器需要告诉服务器自己希望能够接收什么样的数据,需要什么样的压缩格式,什么语言,哪种字符集等;
而服务器需要告诉客户端自己能够提供的服务是什么。
内容协商的几种概念
内容协商标头
Accept
HTTP请求标头会告知客户端能够接收的MIME类型是什么
接受请求HTTP标头会通告客户端自己能够接受的MIME类型
什么是MIME ?
MIME:MIME(MultipurposeInternetMailExtensions)
是描述消息内容类型的因特网标准,
MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
什么是MIME类型呢?
MIME类型其实就是一系列消息内容类型的集合
那么MIME类型都有哪些呢?
文本文件:text/html、text/plain、text/css、application/xhtml+xml、application/xml
图片文件:image/peg, image/gif、image/png
视频文件:video/mpeg、video/quicktime
应用程序二进制文件:application/octet-stream、application/zip
比如, 如果浏览器不支持PNG图片的显示, 那Accept就不指定image/png, 而指定可处理的image/gif和image/jpeg等图片类型。
一般MIME类型也会和q这个属性一起使用
q表示的是权重, 来看一个例子
q是什么?q表示的是权重, 来看一个例子
这是什么意思呢?若想要给显示的媒体类型增加优先级,则使用q=来额外表示权重值,
没有显示权重时,默认值是1.0
没有显示权重时,默认值是1.0
也就是说, 这是一个放置顺序, 权重高的在前, 低的在后, application/xml; q=0.9是不可分割的整体。
Accept-Charset
Accept-Charset表示客户端能够接受的字符编码。
Accept-charset属性规定服务器处理表单数据所接受的字符编码
Accept-charset属性允许你指定一系列字符集,服务器必须支持这些字符集,从而得以正确解释表单中的数据。
Accept-Charset也是属于内容协商的一部分
Accept-Charset没有对应的标头, 服务器会把这个值放在Content-Type中用charset=xxx来表示
它和Accept一样, 也可以用q来表示字符集, 用退号进行分割
例如
Accept-Charset
例如, 浏览器请求GBK或UTF-8的字符集, 然后服务器返回的是UTF-8编码,
就是下面这样
Accept-Charset:gbk, utf-8
Content-Type:text/htmL;charset-utf-8
Content-Type:text/htmL;charset-utf-8
事实上, 很多以Accept-*开头的标头, 都是属于内容协商的范畴, 关于内容协商我们下面会说。
Accept-Language
首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集(指中文或英文等) , 以及自然语言集的相对优先级。
Accept-Language请求表示客户端需要服务端返回的语言类型,
Accept-Language也属于内容协商的范畴。
服务端通过Content-Language进行响应,
和Accept首部字段一样, 按权重值q=来表示相对优先级。
可一次指定多种自然语言集。
例如
Accept-Language:de
Accept-Language:de-CH
AcceptLanguage:en-US,en;q=0.5
Accept-Language:de-CH
AcceptLanguage:en-US,en;q=0.5
Accept-Encoding
表示HTTP标头会标明客户端希望服务端返回的内容编码, 这通常是一种压缩算法,
Accept-Encoding也是属于内容协商的一部分,
使用并通过客户端选择Content-Encoding内容进行返回。
即使客户端和服务器都能够支持相同的压缩算法,服务器也可能选择不压缩井返回,
这种情况可能是由于这两种情况造成的
要发送的数据已经被压缩了一次,第二次压缩并不会导致发送的数据更小
服务器过载, 无法承受压缩带来的性能开销, 通常, 如果服务器使用CPU超过80%,Microsoft则建议不要使用压缩
下面是Accept-Encoding的使用方式
Accept-Encoding:gzip
由文件压缩程序gzip生成的编码格式, 使用Lempel-Ziv编码(LZ 77) 和32位CRC的压缩格式,
感兴趣的同学可以读一下(https://en.wikipedia.org/wiki/LZ77andLZ78#LZ77)
Accept-Encoding:compress
使用Lempel-Ziv-Welch(LZW) 算法的压缩格式,
有兴趣的同学可以读(https://en.wikipedia.org/wiki/LZW)
Accept-Encoding:deflate
使用zlib结构和deflate压缩算法的压缩格式,
参考(https://en.wikipedia.org/wiki/Zlib) 和(https://en.wikipedia.org/wiki/DEFLATE)
Accept-Encoding:br
使用Broti算法的压缩格式
参考(https://en.wikipedia.org/wiki/Brotli)
不执行压缩或不会变化的默认编码格式
Accept-Encoding:identity
Accept-Encoding:*
*:匹配标头中未列出的任何内容缩码,
如果没有列出Accept-Encoding, 这就是默认值
并不意味着支持任何算法,只是表示没有偏好
Accept-Encoding:deflate, gzip; q=1.0, *; q=0.5
;q-采用权重q值来表示相对优先级, 这点与首部字段Accept相同
上面的几种表述方式就已经把Accept-Encoding的属性列全了
Content-Type
HTTP响应标头Content-Type说明了实体内对象的媒体类型,
和首部字段Accept一样使用, 表示服务器能够响应的媒体类型。
Content-Type实体标头,用于指示资源的MIME类型。
作为响应, Content-Type标头告诉客户端返回的内容的内容类型实际上是什么。
Content-type有两种值:MIME类型和字符集编码,
例如Content-Type:text/html;charset-UTF-8
在某些情况下, 浏览器将执行MIME嗅探, 并且不一定遵循此标头的值:为防止此行为, 可以将标头X-Content-Type-Options设置为no sniff,
Content-Encoding
上面讲过Accept Encoding是客户端希望服务端返回的内容编码, 但是实际上服务端返回给客
户端的内容编码实际上是通过Content-Encoding返回的。
户端的内容编码实际上是通过Content-Encoding返回的。
Content-Encoding实体标头用于压缩媒体类型,
它让客户端知道如何进行解码操作, 从而使客户端获得Content-Type标头引用的MIME类型。
内容编码是指在不丢失实体信息的前提下所进行的压缩。
主要也是四种, 和Accept-Encoding相同, 它们是gzip、compress、deflate、identity.
下面是一组请求/响应内容压缩编码
Accept-Encoding:gzip,deflate
Content-Encoding:gzip
Content-Encoding:gzip
表示如下
Content-Encoding:gzip
Content-Encoding:compress
Content-Encoding:deflate
Content-Encoding:identity
Content-Encoding:br
Content-Encoding:gzip, identity
Content-Encoding:deflate, gzip
Content-Encoding:compress
Content-Encoding:deflate
Content-Encoding:identity
Content-Encoding:br
Content-Encoding:gzip, identity
Content-Encoding:deflate, gzip
Content-Language
首部字段Content-Language会告知客户端, 服务器使用的自然语言是什么,
它与Accept-Language相对,下面是一组请求/响应使用的语言类型
例如
Content-Language:de-DE
Content-Language:en-US
Content-Languoge:de-DE,en-CA
Content-Language:en-US
Content-Languoge:de-DE,en-CA
Content-Language实体标头用于描述面向受众的语言, 以便使用户根据用户自己的首选语言进行区分
下面根据内容协商对应的请求/响应标头, 列了一张图供参考
内容协商对应的请求/响应标头
注意:其中Accept-Charset没有对应的Content-Charset, 而是通过Content-Type来表示。
HTTP认证
HTTP提供了用于访问控制和身份认证的功能, 下面就对HTTP的权限和认证功能进行介绍
通用HTTP认证框架
RFC 7235定义了HTTP身份认证框架, 服务器可以根据其文档的定义来检查客户端请求。客户端也可以根据其文档定义来提供身份验证信息。
请求/响应的工作流程如下:
服务器以401(未授权)的状态响应客户端告诉客户端服务器需要认证信息,
客户端提供至少一个wwww-Authenticate的响应标头进行授权信息的认证。
想要通过服务器进行身份认证的客户端可以在请求标头字段中添加认证标头进行身份认证,
一般的认证过程图解
一般的认证过程如下
一般认证过程描述
首先客户端发起一个HTTP请求, 不带有任何认证标头,
服务器对此HTTP请求作出响应, 发现此HTTP信息未带有认证凭据,
服务器通过www-Authenticate标头返回401告诉客户端此请求未通过认证。
然后客户端进行用户认证, 认证完毕后重新发起HTTP请求, 这次HTTP请求带有用户认证凭据
(注意, 整个身份认证的过程必须通过HTTPS连接保证安全) ,
(注意, 整个身份认证的过程必须通过HTTPS连接保证安全) ,
到达服务器后,服务器会检查认证信息
如果不符合服务器认证信息, 会返回403 Forbidden表示用户认证失败
如果满足认证信息,则返回200 OK
客户端和服务器之间的HTTP连接可以被代理缓存重新发送, 所以认证信息也适用于代理服务器。
代理认证
由于资源认证和代理认证可以共存,因此需要不同的头和状态码,在代理的情况下,会返回状态码407(需要代理认证) ,
Proxy-Authorization请求头,用于将证书提供给代理服务器。
Proxy-Authenticate响应头,包含至少一个适用于代理的情况,
下面分别来认识一下这两个标头
Proxy-Authorization(请求头、代理认证)
Proxy-Authorization是属于请求与认证的范畴, 在上面提到一个认证的HTTP标头是Authorization,
这个HTTP请求标头和Proxy-Authenticate拼接很相似, 但是概念不同
这个标头用于向代理服务器提供凭据
不同于Authorization发生在客户端-服务器之间:Proxy-Authorization发生在代理服务器和客户端之间。
它表示接收到从代理服务器发来的认证时, 客户端会发送包含首部字段Proxy-Authorization的请求, 以告知服务器认证所需要的信息。
Proxy-Authorization:Basic YWxhZGRpbjpvcGVuc2VzYW1L
Proxy-Authenticate(响应头、代理认证)
HTTP响应标头Proxy-Authenticate会定义认证方法, 应该使用身份验证方法来访问代理服务器后面的资源,即客户端。
它与HTTP客户端和服务端之间的访问认证行为相似, 不同之处在于Proxy-Authenticate的认证双方是客户端与代理之间
它将请求认证到代理服务器,从而允许它进一步发送请求。
Proxy-Authenticate:Basic
Proxy-Authenticate:Basic realm="Access to the internal site"
Proxy-Authenticate:Basic realm="Access to the internal site"
下面是代理服务器的请求/响应认证过程
代理服务器的请求/响应认证过程
这个过程和通用的过程类似,我们就不再详细展开描述了。
禁止访问
如果代理服务器收到的有效凭据不足以获取对给定资源的访问权限,则服务器应使用403 Forbidden状态代码进行响应。
与401 Unauthorized和407 Proxy Authorization Required不同, 该用户无法进行身份验证。
WWW-Authenticate和Proxy-Authenticate头
WWW-Authenticate和Proxy-Authenticate响应头定义了获得对资源访问权限的身份验证方法。
他们需要指定使用哪种身份验证方案,以便希望授权的客户端知道如何提供凭据。
它们的一般表示形式如下
WWW-Authenticate:<type>realm = <realm>
Proxy-Authenticate:<type>realm=<realm>
Proxy-Authenticate:<type>realm=<realm>
<type>介绍
<type>是认证协议
Basic是下面协议中最普遍使用的
RFC 7617中定义了Basic HTTP身份验证方案,
该方案将凭据作为用户ID/密码对传输, 并使用base 64进行编码。
(感兴趣的同学可以看看https://tools.ietf.org/html/rfc7617)
其他的认证协议主要有
其他的认证协议
realm介绍
realm用于描述保护区或指示保护范围
这可能是诸如Access to the staging site(访问登陆站点)或者类似的,这样用户就可以知道他们要访问哪个区域。
Authorization和Proxy-Authorization标头
Authorization和Proxy-Authorization请求标头,包含用于通过代理服务器对用户代理进行身份验证的凭据。
在此,再次需要类型,其后是凭据,取决于使用哪种身份验证方案,可以对凭据进行编码或加密。
一般表示如下
Authorization:Basic YWxhZGRpbjpvcGVuc2VzYW1l
Proxy-Authorization:BasicYWxhZGRpbjpvcGVuc2VzYW1L
Proxy-Authorization:BasicYWxhZGRpbjpvcGVuc2VzYW1L
HTTP缓存
为什么需要HTTP缓存 ?
通过把请求 响应缓存起来有助于提升系统的性能, Web缓存减少了延迟和网络传输量, 因此减少资源获取锁需要的时间。
由于链路漫长, 网络时延不可控, 浏览器使用HTTP获取资源的成本较高。
所以, 非常有必要把数据缓存起来, 下次再请求的时候,尽可能地复用。
当Web缓存在其存储中具有请求的资源时,它将拦截该请求并直接返回资源,而不是到达源服务器重新下载井获取。
这样做可以实现两个小目标
减轻服务器负载
提升系统性能
目前主要讨论浏览器缓存和代理编存
目前主要讨论浏览器缓存和代理编存
但真实情况不只有这两种缓存,还有其他缓存方案
网关缓存
CDN反向代理缓存
负载平衡器
把它们部署在Web服务器上, 可以提高网站和Web应用程序的可靠性,性能和可伸缩性。
HTTP缓存都有哪些
HTTP缓存有几种不同的类型, 这些可以分为两个主要类别:私有缓存和共享缓存。
在计算机网络中, 分为两种缓存
(常见的通用标头-Cache-Control)
共享缓存 Public Cache
共享缓存 Public Cache
共享缓存是一种用于存储要由多个用户重用的响应缓存。
public属性只出现在客户端响应中, 表示响应可以被任何缓存所缓存。
共享缓存是一种缓存,它可以存储多个用户重复使用的请求/响应。
共享缓存一般使用public来表示,
它的一般表示方法如下
Cache-Control:public
共享缓存示意图
共享缓存示意图
私有缓存Private Cache
可以使用private来实现私有缓存,
私有缓存也称为专用缓存,它只适用于单个用户
当指定private指令后, 响应只以特定的用户作为对象
这与public的用法相反, 缓存服务器只对特定的客户端进行缓存,其他客户端发送过来的请求,缓存服务器则不会返回缓存。
私有缓存只用来缓存单个用户,你可能在浏览器设置中看到了缓存,浏览器缓存包含服务器通过HTTP下载下来的所有文档。
这个高速缓存用于使访问的文档可以进行前进/后退, 保存操作而无需重新发送请求到源服务器。
它的一般表示方法如下
Cache-Control:private
私有缓存示意图
私有缓存示意图
不缓存过期资源
所有的请求都会直接到达服务器,由服务器来下载资源并返回。
不缓存过期资源即浏览器和代理不会缓存过期资源,客户端发起的请求会直接到达服务器,
使用no-cache指令的目的是为了防止从缓存中返回过期的资源
可以使用no-cache标头代表不缓存过期资源。
no-cache属于Cache-Control通用标头
no-cache很容易和no-store混淆
一般都会把no-cache认为是不缓存, 其实不是这样。
no-cache示意图
no-cache示意图
其一般的表示方法如下
Cache-Control:no-cache
也可以使用max-age=0来实现不缓存的效果。
Cache-Control:max-age=0
举个例子
No-Cache就相当于是吃着碗里的, 占着锅里的,
如果锅里还有新的肉片, 就先吃锅里的,如果锅里没有新的,再吃自己的,
这里锅里的就相当于是源服务器产生的,碗里的就相当于是缓存的。
缓存控制
HTTP/1.1中的Cache-Control常规标头字段用于执行缓存控制, 使用此标头可通过其提供的各种指令来定义缓存策略。
Cache-Control的属性
不缓存
no-store才是真正意义上的不缓存
每次服务器接受到客户端的请求后, 都会返回最新的资源给客户端。
Cache-Control:no-store
缓存但需要验证
同上面的不缓存过期资源
私有和共享缓存
同上
缓存过期
缓存中一个很重要的指令就是max-age, 这是资源被视为新鲜的最长时间,
与Expires相反, 此指令是相对于请求时间的, 对于应用程序中不会更改的文件, 通常可以添加主动緩存。
下面是mag-age的表示
Cache-Control:max-age=31536080
缓存验证
must-revalidate表示缓存必须在使用之前验证过时资源的状态, 并且不应使用过期的资源
Cache-Control:must-revalidate
下面是一个缓存验证图
缓存验证图
什么是新鲜的数据
一旦资源存储在缓存中,理论上就可以永远被缓存使用。
但是不管是浏览器缓存还是代理缓存,其存储空间是有限的, 所以缓存会定期进行清除, 这个过程叫做缓存回收(cache eviction)(自译)
另一方面, 服务器上的缓存也会定期进行更新,
HTTP作为应用层的协议, 它是一种客户-服务器模式
HTTP是无状态的协议, 因此当资源发生更改时, 服务器无法通知缓存和客户端。
因此服务器必须通过某种方式告知客户端缓存已经被更新。
服务器会提供过期时间这个概念,告知客户端在此到期时间之前,资源是新鲜的,也就是未更改过的。
在此到期时间的范围之外,资源已过时。
过期算法(Eviction algorithms) 通常会将新资源优先于陈旧资源使用。
注意:
过期的资源并不会被回收或忽略,
当高速缓存接收到过期资源时,它会使用If-None-Match转发此请求, 以检查它是否仍然有效,
如果有效, 服务器会返回304 Not Modified响应,并且没有任何响应体,从而节省了一些带宽
图解使用共享缓存代理的过程
图解使用共享缓存代理的过程
只说一下Age的作用, Age是HTTP响应标头告诉客户端源服务器在多久之前创建了响应, 它的单位为秒,
Age标头通常接近于0
如果是0则可能是从源服务器获取的
如果不是表示可能是由代理服务器创建,那么Age的值表示的是缓存后的响应再次发起认证到认证完成的时间值。
缓存的有效性
缓存的有效性是由多个标头来共同决定的, 而并非某一个标头来决定。
如果指定了Cache-control:max-age=N,那么缓存会保存N秒,如果这个通用标头不存在的话,则会检查是否存在Expires标头。
如果Exprires标头存在, 那么它的值减去Date标头的值就可以确定其有效性。
最后, 如果max-age和expires都不存在, 就去寻找Last-Modified标头,
如果存在此标头, 则高速缓存的有效性等于Date标头的值减去Last-modified标头的值除以10,
缓存验证
当到达缓存资源的有效期时,将对其进行验证或再次获取。
仅当服务器提供了强验证器或弱验证器时,才可以进行验证。
当用户按下重新加载按钮时,将触发重新验证。
如果缓存的响应包含Cache-control:must-revalidate标头, 则在正常浏览下也会触发该事件。
另一个因素是高级→缓存首选项面板中的缓存验证首选项。
有一个选项可在每次加载文档时强制进行验证.
Etag的三个常见用法
Etag实现验证器功能
强验证器和弱验证器, 实现验证器功能的标头正式Etag的作用,
这意味着HTTP用户代理(例如浏览器) 不知道该字符串表示什么, 并且无法预测其值。
如果Etag标头是资源响应的一部分, 则客户端可以在未来请求的标头中发出If-None-Match, 以验证缓存的资源。
Last-Modified响应标头可以用作弱验证器, 因为它只有1秒可以分辨的时间。
如果响应中存在Last-Modified标头, 则客户端可以发出If-Modified-Since请求标头来验证缓存资源。
使用Etag和If-Match标头,避免碰撞
通过使用Etag和If-Match标头, 你可以检测避免碰撞。
例如
在编辑MDN时, 将对当前Wiki内容进行哈希处理并将其放入响应中的Etag中
Etag:"33a64df551425fc c55e4d42a148795d9f25f89d 4”
当将更改保存到Wiki页面(发布数据) 时, POST请求将包含If-Match标头, 其中包含Etag值以检查有效性。
If-Match:"33a64df551425fc cS5e4d42a148795d9f25f89d 4"
如果哈希值不匹配, 则表示文档已在中间进行了编辑, 并返回412 Precondition Failed错误。
缓存未占用资源
Etag标头的另一个典型用法是缓存未更改的资源,
如果用户再次访问给定的URL(已设置Etag) , 并且该URL过时, 则客户端将在If-None-Match标头字段中发送其Etag的值
If-None-Match:“33a64df551425fc c55e4d42a148795d9f25f89d 4"
服务器将客户端的Etag(通过If None-Match发送) 与Etag进行比较, 以获取其当前资源版本
如果两个值都匹配(即资源未更改) , 则服务器会发回304 Not Modified状态, 没有主体, 它告诉客户端响应的缓存仍然可以使用。
HTTP CROS跨域
CROS的全称是Cross-Origin Resource Sharing (CROS) , 中文译为跨域资源共享, 它是一种机制。
是一种什么机制呢?
它是一种让运行在一个城(origin) 上的Web应用被准许访问来自不同源服务器上指定资源的机制,
什么是域(origin),什么是同源策略
Web概念中域(Origin) 的内容由以下三者共同定义
scheme(protocol) -协议
host(domain) -主机
port-端口
用于访问它的URL的端口
仅仅当scheme、host、port都匹配时, 两个对象才有相同的来源.
这种协议相同, 域名相同, 端口相同的安全策略也被称为同源策略(5ame Origin Policy) .
某些操作仅限于具有相同来源的内容, 可以使用CORS取消此限制。
同源策略
处于安全的因素, 浏览器限制了从脚本发起跨域的HTTP请求。
XMLHttpRequest和其他Fetch接口会遵循同源策略(some-origin policy) ,
也就是说使用这些API的应用程序想要请求相同的资源, 那么他们应该具有相同的来源, 除非来自其他来源的响应包括正确的CORS标头也可以。
同源策略是一种很重要的安全策略
它限制了从一个来源加载的文档或脚本如何与另一个来源的资源进行交互。
它有助于隔离潜在的恶意文档,减少可能的攻击媒介,
如果两个URL具有相同的协议、主机和端口号(如果指定) 的话, 那么两个URL具有相同的来源。
实例判断是否同源以及是否跨域,总结跨域的特点
下面是跨域问题的例子,看看你是否清楚什么是跨域了
案例1
是否具有跨域问题呢?
(1)http://example.com/opp1/index.html
(2)http://example.com/app 2/index.html
(2)http://example.com/app 2/index.html
上面两个URL是不具有跨域问题的, 因为这两个URL具有相同的协议(scheme) 和主机(host)
案例2
是否具有跨域问题呢?
http://Example.com:80
http://example.com
http://example.com
这两个URL也不具有跨域问题, 为什么不具有, 端口不一样啊。
其实它们两个端口是一样的。
或许你会认为这两个URL是不一样的, 放心, 关于一样不一样的论据我给你抛出来了
协议和域名部分是不区分大小写的, 但是路径部分则根据服务器平台而定。
Windows和Mac OS X系统是不区分大小写的, 而采用UNIX和Linux系的服务器系统是区分大小写的,
也就是说,上面的Excmple.com和example.com其实是一个网址,并且由于两个地址具有相同的scheme和host,
默认情况下服务器通过端口80传递HTTP内容, 所以上面这两个地址也是相同的。
案例3
是否具有跨域问题?
http://example.com/app1
https://example.com/app2
https://example.com/app2
这两个URL的scheme不同, 所以这两个URL具有跨域问题
案例4
是否具有跨域问题
http://example.com
http://www.example.com
http://myapp.example.com
http://www.example.com
http://myapp.example.com
这三个URL也是具有跨域问题的, 因为它们隶属于不通服务器的主机host
案例5
是否具有跨域问题
http://example.com
http://example.com:8089
http://example.com:8089
这两个URL也是具有跨域问题, 因为这两个URL的默认端口不一样。
案例6
目标来源http://store.company.com/dir/page.html
现在我带你认识了两遍不同的源, 现在你应该知道如何区分两个URL是否属于同一来源了吧!
哪些请求会产生跨域请求呢?
调用XMLHttpRequest或者Fetch API.
XMLHttpRequest是什么?
所有的现代浏览器都有一个内置的XMLHttpReqeust对象, 这个对象可以用于从服务器请求数据。
XMLHttpRequest对于开发人员来说很重要
XMLHttpRequest对象可以用来做下面这些事情
·更新网页无需重新刷新页面
·页面加载后从服务器请求数据
·页面加载后从服务端获取数据
·在后台将数据发送到服务器
使用XMLHttpRequest(XHR) 对象与服务器进行交互, 可从URL检索数据从而不必刷新整个页面, 这使网页可更新页面一部分, 而不中断用户操作。
XMLHttpRequest在AJAX异步编程中使用很广泛
Fetch API是什么?
Fetch提供了请求和响应对象(以及其他网络请求) 的通用定义。
提供了相关概念的定义, 例如CORS和HTTP Origin头语义, 并在其他地方取代了它们各自的定义。
Web字体
(用于CSS中@font-face中的跨域字体使用)
以便服务器可以部署TrueType字体,这些字体只能由允许跨站点加载和使用的网站使用。
Web GL纹理
使用drawImage() 绘制到画布上的图像/视频帧
图片的CSS形状
跨域功能概述
跨域资源共享标准通过添加新的HTTP标头来工作, 这些标头允许服务器描述允许哪些来源从Web浏览器读取信息。
另外, 对于可能导致服务器数据产生副作用的HTTP请求方法(尤其是GET或者具有某些MIME类型POST方法以外HTTP方法) ,
该规范要求浏览器预检请求, 使用HTTP OPTIONS请求方法从服务器请求受支持的方法,然后在服务器批准后发送实际请求。
服务器还可以通知客户端是否应与请求一起发送凭据(例如Cookies和HTTP身份验证) .
注意:CORS故障会导致错误, 但是出于安全原因, 该错误的详细信息不适用于JavaScript, 所有代码都知道发生了错误。
确定具体出问题的唯一方法是查看浏览器的控制台以获取详细信息。
访问控制
简单请求
一些请求不会触发CORS预检(关于预检我们后面再介绍) 。
简单请求是满足一下所有条件的请求
(1)允许以下的方法:GET、HEAD和POST
(2)除了由用户代理自动设置的标头(例如Connection、User-Agent或者在Fetch规范中定义为禁止标头名称的其他标头) 外,
唯一允许手动设置的标头是那些Fetch规范将其定义为CORS安全列出的请求标头,它们是:
唯一允许手动设置的标头是那些Fetch规范将其定义为CORS安全列出的请求标头,它们是:
Accept
Accept-Language
Content-Language
Content-Type
DPR
Downlink
Save-Data
Viewport-Width
Width
Accept-Language
Content-Language
Content-Type
DPR
Downlink
Save-Data
Viewport-Width
Width
(3)Content-Type标头的唯一允许的值是
application/x-www-form-urlencoded
multipart/form-data
text/plain
multipart/form-data
text/plain
(4)没有在请求中使用的任何XMLHttpRequest Upload对象上注册事件侦听器;
这些可以使用XMLHttpRequest.upload属性进行访问。
(5)请求中未使用Readable Stream对象
下面是一个简单请求事例
例如, 假定web内容https://foo.example想要获取https://bar.other域的资源,
那么JavaScript中的代码可能会像下面这样写
JavaScript中的代码可能会像下面这样写
这使用CORS标头来处理特权, 从而在客户端和服务器之间执行某种转换。
子主题
在这种情况下浏览器将发送到服务器的内容(浏览器将发送到服务器的内容)
注意请求的标头Origin, 它表明调用来自于https://foo.example
让我们看看服务器是如何响应的(服务器如何响应)
服务端发送Access-Control-Allow-Origin作为响应。
使用Origin标头和Access-Control-Allow-Origin展示了最简单的访问控制协议。
在这个事例中, 服务端使用Access-Control-Allow-Origin作为响应, 也就说明该资源可以被任何域访问。
如果位于https://bar.other的资源所有者希望将对资源的访问限制为仅来自https://foo.example的请求,
他们应该发送如下响应Access-Control-Allow-Origin:https://foo.example
他们应该发送如下响应Access-Control-Allow-Origin:https://foo.example
现在除了https://foo.exomple之外的任何域都无法以跨域方式访问到https://bar.other的资源
预检请求
和上面探讨的简单请求不同,
预检请求首先通过OPTIONS方法向另一个域上的资源发送HTTP请求,用来确定实际请求是否可以安全的发送。
跨站点这样被预检,因为它们可能会影响用户数据。
下面是一个预检请求事例
创建了一个XML请求体
上面的事例创建了一个XML请求体,用来和POST请求一起发送。
此外, 设置了非标准请求头X-PINGOTHER, 这个标头不是HTTP/1.1的一部分, 但通常对Web程序很有用
由于请求的Content-Type使用application/xmL, 井且设置了自定义标头, 因此该请求被预检
如下图所示
如下图所示
如下所述, 实际的POST请求不包含Access-Control-Request-* 标头; 只有OPTIONS请求才需要它们.
下面我们来看一下完整的客户端/服务器交互
(1)预检请求
首先是预检请求 ,预检请求使用OPTIONS方法,
浏览器根据上面的JS代码段所使用的请求参数确定是否需要发送此请求,以便服务器可以响应是否可以使用实际请求参数发送请求。
OPTIONS是一种HTTP/1.1方法, 用于确定来自服务器的更多信息, 并且是一种安全的方法, 这意味着它不能用于更改资源。
请注意, 与OPTIONS请求一起, 还发送了另外两个请求标头
Access-Control-Request-Method:POST
作为预检请求的一部分通知服务器
当发送实际请求时, 将使用POST请求方法发送该请求,
Access-Control-Request-Headers:X-PINGOTHER, Content-Type
通知服务器, 当发送请求时, 它将与X-PINGOTHER和Content-Type自定义标头一起发送。
服务器可以确定这种情况下是否接受请求。
(2)预检响应
首先是预检响应(服务器发回的响应)
表示POST请求和X-PING OTHER是可以接受的
Access-Control-Allow-Origin:http://foo.example
服务器完成响应表明源http://foo.example是可以接受的URL,
Access-Control-Allow-Methods:POST, GET, OPTIONS
能够允许POST, GET、OPTIONS进行请求
Access-Control-Allow-Headers:X-PINGOTHER, Content-Type
允许自定义标头X-PING OTHER, Content-Type。
Access-Control-Max-Age:86400
最后, Access-Control-Max-Age以秒为单位给出一个值,
这个值表示对预检请求的响应可以缓存多长时间, 在此期间内无需发送其他预检请求。
(3)完成预检请求后,将发送实际请求:
发送实际请求
收到服务器的实际响应
带凭证的请求
XMLHttpRequest或Fetch和CORS最有趣的功能就是,能够发出知道HTTP Cookie和HTTP身份验证的凭证请求。
默认情况下, 在跨站点XMLHttpRequest或Fetch调用中, 浏览器将不发送凭据,
调用XMLHttpRequest对象或Request构造函数时,必须设置一个特定的标志。
下面是一个带凭证的请求事例
在下面这个例子中,最初从http://foo.example加载的内容对设置了Cookies的http://bar.other上的资源进行了简单的GET请求,
foo.example上可能的代码如下
foo.example上可能的代码如下
invocation.with Credentials=true;
显示XMLHttpRequest上的标志, 必须设置该标志才能使用Cookie进行调用。
默认情况下, 调用是不在使用Cookie的情况下进行的。
由于这是一个简单的GET请求, 因此不会进行预检,
但是,浏览器将拒绝任何没有Access-Control-Allow-Credentials的响应:
标头为true, 指的是响应不会返回web页面的内容。
上面的请求用下图可以表示
图解
这是客户端和服务器之间的示例交换:
客户端 发送的请求
上面第10行包含指向http://bar.other上的内容Cookie,
服务器响应的内容
但是如果bar.other没有以Access:Control-Allow-Credentials:true响应(下面第五行),
响应将被忽略,并且不能使用网站返回的内容。
请求凭证和通配符
当回应凭证请求时, 服务器必须在Access-Control-Allow-Credentials中指定一个来源, 而不能直接写*通配符
因为上面示例代码中的请求标头包含Cookie标头, 如果Access-Control-Allow-Credentials中是指定的通配符*的话,请求会失败。
注意上面示例中的Set-Cookie响应标头还设置了另外一个值, 如果发生故障, 将引发异常(取决于所使用的API) 。
HTTP响应标头
下面会列出一些服务器跨域共享规范定义的HTTP标头,
上面简单概述了一下, 现在一起来认识一下,主要会介绍下面这些
Access-Control-Allow-Origin
Access-Control-Allow-Origin是HTTP响应标头
指示响应是否能够和给定的源共享资源。
指定单个资源,告诉浏览器允许指定来源访问资源。
对于没有凭据的请求*通配符,告诉浏览器允许任何源访问资源。
例如,如果要允许源https://mozilla.org的代码访问资源,可以使用如下的指定方式
Access-Control-Allow-Origin:https://mozilla.org
Vary:Origin
Vary:Origin
如果服务器指定单个来源,而不是*通配符, 则服务器还应在Vary响应标头中包含该来源
Access-Control-Allow-Credentials
Access-Control-Allow-Credentials 是 HTTP响应标头
这个标头告诉浏览器, 当包含凭证请求(Request.credentials) 时是否将响应公开给前端JS代码。
Request是什么
Request是Fetch API的一类接口,代表着资源请求。
一般创建Request对象有两种方式
使用Request()构造函数创建一个Request对象
通过FetchEvent.request api操作来创建
Request.credentials是什么
Request接口的凭据只读属性指示,在跨域请求的情况下,用户代理是否应从其他域发送cookie
(其他Request对象的方法详见https://developer.mozilla.org/en-US/docs/Web/API/Request
当发送的是凭证模式的请求包含(Request.credentials) 时,
如果Access-Contro-Allow-Credentials值为true, 浏览器将仅向前端JavaScript代码公开响应。
Access-Control-Allow-Credentials:true
当用作对预检请求响应的一部分时, 这表明是否可以使用凭据发出实际请求。注意简单的GET请求不会进行预检。
凭证一般包括三个内容
cookie
认证头
TLS客户端证书
可以参考一个实际的例子
https://www.jianshu.com/p/ea485e5665b3
Access-Control-Allow-Headers
Access-Control-Allow-Headers是一个响应标头,
这个标头用来响应预检请求, 它发出实际请求时可以使用哪些HTTP标头。
示例
自定义标头
这是Access-Control-Allow-Headers标头的示例。
它表明除了像CROS安全列出的请求标头外, 对服务器的CROS请求还支持名为X-Custom-Header的自定义标头
Access-Control-Allow-Headers:X-Custom-Header
多个标头
这个例子展示了Access-Control-Allow-Headers如何使用多个标头
Access-Control-Allow-Headers:X-Custom-Header, Upgrade-Insecure-Requests
绕过其他限制
尽管始终允许使用CORS安全列出的请求标头, 并且通常不需要在Access-Control-Allow-Headers中
列出这些标头,但是无论如何列出它们都将绕开适用的其他限制。
列出这些标头,但是无论如何列出它们都将绕开适用的其他限制。
Access-Control-Allow-Headers:Accept
哪些是CORS列出的安全标头?
有下面这些Accept、Accept-Language、Content-Language、Content-Type,
当且仅当包含这些标头时, 无需在CORS上下文中发送预检请求。
Access-Control-Allow-Methods
Access-Control-AlLow-Methods也是响应标头
它指定了哪些访问资源的方法可以使用预检请求。
Access-Control-Allow-Methods:POST, GET, OPTIONS
Access-Control-Allow-Methods:*
Access-Control-Allow-Methods:*
Access-Control-Expose-Headers
Access-Control-Expose-Headers响应标头
表明哪些标头可以作为响应的一部分公开,
默认情况下, 仅公开6个CORS安全列出的响应标头, 分别是
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
如果希望客户端能够访问其他标头, 则必须使用Access-Control-Expose-Headers标头列出它们
下面是示例
要公开非CORS安全列出的请求标头, 可以像如下这样指定
Access-Control-Expose-Headers:Content-Length
要另外公开自定义标头, 例如X-Kuma-Revision, 可以指定多个标头, 并用逗号分隔
Access-Control-Expose-Headers:Content-Length, X-Kuma-Revision
在不是凭证请求中,你还可以使用通配符
Access-Control-Expose-Headers:*
但是, 这不会通配Authorization标头, 因此如果需要公开它, 则需要明确列出
Access-Control-Expose-Headers:*, Authorization
Access-Control-Max-Age
Access-Control-Max-Age响应头
表示预检请求的结果可以缓存多长时间
例如
Access-Control-Max-Age:680
表示预检请求可以缓存10分钟
Access-Control-Request-Headers
浏览器在发出预检请求时,使用Access-Control-Request-Headers请求标头
使服务器知道,在发出实际请求时,客户端可能发送的HTTP标头。
Access-Control-Request-Headers:X-PINGOTHER, Content-Type
Access-Control-Request-Method
同样的, Access-Control-Request-Method响应标头
告诉服务器发出预检请求时将使用那种HTTP方法。
此标头是必需的, 因为预检请求始终是OPTIONS, 并且使用的方法与实际请求不同。
Access-Control-Request-Method:POST
Origin
Origin请求标头表明匹配的来源
它不包含任何信息, 仅仅包含服务器名称
它与CORS请求以及POST请求一起发送
它类似于Referer标头, 但与此标头不同, 它没有公开整个路径。
例如
Origin:https://developer.mozilla.org
HTTP条件请求
HTTP具有条件请求的概念, 通过比较资源更新生成的值与验证器的值进行比较, 来确定资源是否进行过更新。
这样的请求对于验证缓存的内容、条件请求、验证资源的完整性来说非常重要。
HTTP条件请求的原则
HTTP条件请求是根据特定标头的值执行不同的请求, 这些标头定义了一个前提条件,
如果前提条件匹配或不匹配,则请求的结果将有所不同
对于安全的方法
像是GET、用于请求文档的资源, 仅当条件请求的条件满足时发回文档资源,这种方式可以节约带宽
什么是安全的方法
对于HTTP来说, 安全的方法是不会改变服务器状态的方法
换句话说, 如果方法只是只读操作, 那么它肯定是安全的方法,
比如说GET请求, 它肯定是安全的方法, 因为它只是请求资源。
几种常见的方法肯定是安全的, 它们是GET、HEAD和OPTIONS,
所有安全的方法都是幂等的 ,但不是所有幂等的方法都是安全的,
例如PUT和DELETE都是幂等的, 但不安全
幂等性(HTTP是幂等的)
如果相同的客户端发起一次或者多次HTTP请求会得到相同的结果, 则说明HTTP是幂等的。
对于非安全方法
像是PUT, 只有原始文档与服务器上存储的资源相同时, 才可以使用条件请求来传输文档。
(PUT方法通常用来传输文件, 就像FTP协议的文件上传一样)
例如PUT和DELETE都是幂等的, 但不安全
验证 与 比较器
比较器是什么?
所有的条件请求都会尝试检查服务器上存储的资源是否与某个特定版本的资源相匹配。
为了满足这种情况,条件请求需要指示资源的版本。
由于无法和整个文件逐个字符进行比较,因此需要把整个文件描绘成一个值,然后把此值和服务器上的资源进行比较,
这种方式称为比较器,
比较器有两个条件
文档的最后修改日期
一个不透明的字符串, 用于唯一标识每个版本, 称为实体标签或Etag。
比较器有两种相等性检查
比较两个资源是否具有相同的版本有些复杂,根据上下文,有两种相等性检查
强验证
强验证保证的是字节级别的验证
严格的验证非常严格,可能在服务器级别难以保证
但是它能够保证任何时候都不会丢失数据,但这种验证丢失性能。
要使用Last-Modified很难实现强验证
通常, 这是通过使用带有资源的MD5哈希值的Etag来完成的。
弱验证
弱验证不同于强验证,因为如果内容相等,它将认为文档的两个版本相同
例如,一个页面与另一个页面的不同之处仅在于页脚的日期不同,因此该页面被认为与其他页面相同
而使用强验证时则被认为这两个版本是不同的。
构建一个弱验证的Etag系统可能会非常复杂,
因为这需要了解每个页面元素的重要性,但是对于优化缓存性能非常有用。
介绍一下Etag如何实现强弱验证
Etag响应头是特定版本的标识
它能够使缓存变得更高效并能够节省带宽
因为如果缓存内容未发生变更, Web服务器则不需要重新发送完整的晌应
除此之外, Etag能够防止资源同时更新互相覆盖。
Etag能够防止资源同时更新互相覆盖
如果给定URL上的资源发生变更, 必须生成一个新的Etag值, 通过比较它们可以确定资源的两个表示形式是否相同。
Etag值有两种
强Etag
字节对字节进行比较
例如在恢复下载时
当期望的是字节对字节进行比较时, 使用强Etag进行验证
HTTP协议默认使用强验证, 它指定何时进行弱验证
无论实体发生多么细微的变化都会改变其值
一般的表示如下
强Etag值
弱Etag
资源是否具有相同的内容
当用户代理需要比较两个资源是否具有相同的内容时, 使用弱Etag进行验证
弱Etag值只用于提示资源是否相同, 只有资源发生了根本改变, 产生差异时才会改变Etag值。
这时, 会在字段值最开始处附加W/
弱Etag值
条件请求的常见标头
If-Match
对于GET和POST方法, 服务器仅在与列出的Etag(销应标头)之一匹配时才返回请求的资源。
对于像是PUT和其他非安全的方法, 在这种情况下,它仅仅将上传资源,
两种常见的案例
对于GET和POST方法
会结合使用Range标头,
它可以确保新发送请求的范围与上一个请求的资源相同。
如果不匹配的话,会返回416响应
对于其他方法, 特别是PUT方法
If-Match可以防止丢失更新
服务器会比对If-Match的字段值和资源的Etag值,
仅当两者一致时, 才会执行请求。
反之, 则返回状态码412Precondition Failed的响应。
例如
子主题
If-None-Match
条件请求, 它与If-Match的作用相反, 仅当If-None-Match的字段值与Etag值不一致时,可处理该请求,
对于GET和HEAD, 仅当服务器没有与给定资源匹配的Etag时, 服务器将返回 200 OK作为响应,
对于其他方法, 仅当最终现有资源的Etag与列出的任何值都不匹配时, 才会处理请求。
当GET和POST发送的If-None-Match与Etag匹配时, 服务器会返回304。
If-None-Match
If-Modified-Since
If-Modified-Since是HTTP条件请求的一部分
只有在给定日期之后, 服务端修改了请求所需要的资源,才会返回200OK的响应。
如果在给定日期之后,服务端没有修改内容,响应会返回304并且不带任何响应体。
If-Modified-Since只能使用GET和HEAD请求。
If-Modified-Since与If-None-Match结合使用时, 它将被忽略, 除非服务器不支持If-None-Match。
一般表示如下
一般表示如下
注意:这是格林威治标准时间, HTTP日期始终以格林尼治标准时间表示, 而不是本地时间。
If-Range
If-Range也是条件请求
如果满足条件(If Range的值和Etag值或者更新的日期时间一致) , 则会发出范围请求,否则将会返回全部资源,
它的一般表示如下
它的一般表示如下
If-Unmodified-Since
If-Unmodified-Since HTTP请求标头也是一个条件请求
服务器只有在给定日期之后没有对其进行修改时,服务器才返回请求资源。
如果在指定日期时间后发生了更新,则以状态码412Precondition Failed作为的应返回。
它的一般表示如下
它的一般表示如下
条件请求三个经典示例
缓存更新
条件请求最常见的示例就是更新缓存
如果缓存是空或没有缓存,则以200 OK的状态发送回请求的资源。
图解缓存更新过程
客户端初始化请求,缓存是空的,没有条件请求,服务器资源返回,并且设置验证器
服务器在收到客户端请求后,设置验证器Last-Modified和Etag标签, 并把这两个标签随着响应一起发送回客户端。
下一次客户端再发送相同的请求后,会直接从缓存中提取,只要缓存没有过期,就不会有任何新的请求到达服务器重新下载资源,
验证器的值用作If-Modified-Since和If-Match标头的参数。
缓存过期后客户端重新发起请求,服务器收到请求后发现如果资源没有更改,服务器会发回304 NotModified响应,
但是,一旦缓存过期,客户端不会直接使用缓存的值,而是发出条件请求。
缓存过期后客户端重新发起请求, 服务器收到请求后发现如果资源没有更改,服务器会发回304 NotModified响应,
这使缓存再次刷新, 并让客户端使用缓存的资源。
尽管有一个响应/请求往返消耗一些资源,但是这比再次通过有线传输整个资源更有效。
如果资源已经发生更改,则服务器仅使用新版本的资源返回200 OK响应,
就像没有条件请求,并且客户端会重新使用新的资源,从这个角度来讲,缓存是条件请求的前置条件.
断点续传
HTTP可以支持文件的部分下载, 通过保留已获得的信息,
此功能允许恢复先前的操作, 从而节省带宽和时间。
断点续传的原理比较简单
图解断点续传
图解断点续传
支持断点续传的服务器通过发送Accept-Ranges标头广播此消息,
一旦发生这种情况, 客户端可以通过发送缺少范围的Ranges标头来恢复下载
子主题
Range
HTTP请求标头
指示服务器应返回文档指定部分的资源, 可以一次请求一个Range来返回多个部分,服务器会将这些资源返回各个文档中。
如果服务器成功返回,那么将返回206响应;
如果Range范围无效, 服务器返回416 Range Not Satisfiable错误;
服务器还可以忽略Range标头,并且返回200作为响应。
实例
表示方法1
表示方法1
表示方法2
还有一种表示是表示方法2
它们分别表示请求前500个字节和最后500个字节,如果范国重叠,则服务器可能会拒绝该请求。
Content-Range
HTTP的Content-Range响应标头
是针对范围请求而设定的, 返回响应时使用首部字段Content-Range
能够告知客户端响应实体的哪部分是符合客户端请求的, 字段以字节为单位。
它的一般表示如下
它的一般表示如下
上段代码表示,从所有67589个字节中返回200-1000个字节的内容
断点续传存在的潜在问题
如果在两次下载资源的期间进行了资源更新,那么获得的范围将对应于资源的两个不同版本,并且最终文档将被破坏,
如何解决这个问题?
为了阻止这种情况的出现,就会使用条件请求
对于范围来说,有两种方法可以做到这一点。
方法1:使用If-Modified-Since和If-Match
图解
如果前提条件失败, 服务器将返回错误; 然后客户端从头开始重新下载。
即使此方法有效,当文档资源发生改变时,它也会添加额外的响应/请求交换,这会降低性能
方法2:使用If-Range
图解
该解决方案效率更高, 但灵活性稍差一些, 因为在这种情况下只能使用一个Etag。
HTTP具有特定的标头来避免这种情况 (If-Range)
通过乐观锁,避免丢失更新
问题描述
Web应用程序中最普遍的操作是资源更新。
这在任何文件系统或应用程序中都很常见, 但是任何允许存储远程资源的应用程序都需要这种机制。
使用put方法, 你可以实现这一点, 客户端首先读取原始文件对其进行修改, 然后把它们发送到服务器。
子主题
上面这种请求响应存在问题,一旦考虑到并发性,事情就会变得不准确。
当客户端在本地修改资源打算重新发送之前,第二个客户端可以获取相同的资源并对资源进行修改操作,这样就会造成问题。
当它们重新发送请求到服务器时,第一个客户端所做的修改将被第二次客户端的修改所覆盖,因为第二次客户端修改并不知道第一次客户端正在修改。
资源提交并更新的一方不会传达给另外一方,所以要保留哪个客户的更改,将随着他们提交的速度而变化:
这取决于客户端,服务器的性能,甚至取决于人工在客户端编辑文档的性能。
例如下面这个流程
子主题
如果没有两个用户同时操作服务器,也就不存在这个问题。
但是,现实情况是不可能只有单个用户出现的,
所以为了规避或者避免这个问题,希望客户端资源在更新时进行提示或者修改被拒绝时收到通知,
解决对策
条件请求允许实现乐观锁算法。
这个概念是允许所有的客户端获取资源的副本,然后让他们在本地修改资源,
并成功通过允许第一个客户端提交更新来控制并发,基于此服务端的后面版本的更新都将被拒绝。
使用If-Match或If-Unmodified-Since标头实现
如果Etag与原始文件不匹配, 或者自获取以来已对文件进行了修改, 则更改为拒绝更新, 并显示412 Precondition Failed错误。
HTTP Cookies 和Session
Cookie是什么?
HTTP协议中的Cookie包括
Web Cookie
浏览器Cookie
它是服务器发送到Web浏览器的一小块数据。
服务器发送到浏览器的Cookie, 浏览器会进行存储,并与下一个请求一起发送到服务器。
Cookie的作用
通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态。
HTTP Cookie机制是HTTP协议无状态的一种补充和改良
Cookie的三个主要目的
会话管理
登陆、购物车、游戏得分或者服务器应该记住的其他内容
个性化
用户偏好、主题或者其他设置
追踪
记录和分析用户行为
曾用客户端存储,现已被替代
Cookie曾经用于一般的客户端存储。
虽然这是合法的, 因为它们是在客户端上存储数据的唯一方法,但如今建议使用现代存储API。
Cookie随每个请求一起发送, 因此它们可能会降低性能(尤其是对于移动数据连接而言) .
客户端存储的现代API是
Web存储API(local Storage和session Storage)
Indexed DB
浏览器内的SQLite,
Indexed DB不属于关系型数据库,是NoSQL。
创建Cookie
当接收到客户端发出的HTTP请求时, 服务器可以发送带有响应的Set-Cookie标头,
Cookie通常由浏览器存储, 然后将Cookie与HTTP标头一同向服务器发出请求。
可以指定到期日期或持续时间,之后将不再发送Cookie,
此外, 可以设置对特定域和路径的限制, 从而限制cookie的发送位置。
Set-Cookie和Cookie标头
Set-Cookie HTTP响应标头将cookie从服务器发送到用户代理。
发送Cookie的例子1
此标头告诉客户端存储Cookie
现在, 随着对服务器的每个新请求, 浏览器将使用Cookie头将所有以前存储的cookie发送回服务器
发送Cookie的例子2
此标头告诉客户端存储Cookie
现在, 随着对服务器的每个新请求,浏览器将使用Cookie头将所有以前存储的cookie发送回服务器
Cookie主要分为三类
会话Cookie(Session Cookies)
Session Cookies
Session Cookies也称为会话Cookies
上面的示例创建的是会话Cookie,
会话Cookie有个特征, 客户端关闭时,Cookie会删除, 因为它没有指定Expires或Max-Age指令。
但是, Web浏览器可能会使用会话还原, 这会使大多数会话Cookie保持永久状态, 就像从未关闭过浏览器一样
如果Cookie不包含到期日期, 则将其视为会话Cookie。
会话Cookie存储在内存中, 永远不会写入磁盘, 当浏览器关闭时, 此后Cookie将永久丢失。
以登录逻辑为例(图解会话Cookie)
在Session Cookies中, 用户的登录状态会保存在服务器的内存中,
当用户登录时, Session就被服务端安全的创建。
在每次请求时, 服务器都会从会话Cookie中读取Sessionld,
如果服务端的数据和读取的Sessionld相同,那么服务器就会发送响应给浏览器,允许用户登录。
图解会话Cookie
以登录逻辑为例(图解会话Cookie)
永久Cookie(Persistent Cookies)
Persistent Cookies
永久性Cookie不会在客户端关闭时过期, 而是在特定日期(Expires) 或特定时间长度(Max-Age) 外过期。
永久Cookie实例
永久Cookie实例
如果Cookie包含有效期, 则将其视为持久性Cookie。
在到期指定的日期, Cookie将从磁盘中删除
Cookie的Secure和Http Only标记
安全的Cookie需要经过HTTPS协议通过加密的方式发送到服务器。
即使是安全的, 也不应该将敏感信息存储在cookie中, 因为它们本质上是不安全的, 并且此标志不能提供真正的保护。
需要了解一下Http Only的作用
Http Only的作用
会话cookie中缺少Http Only属性会导致攻击者可以通过程序(JS脚本、Applet等) 获取到用户的
cookie信息, 造成用户cookie信息泄露, 增加攻击者的跨站脚本攻击威胁。
cookie信息, 造成用户cookie信息泄露, 增加攻击者的跨站脚本攻击威胁。
Http Only是微软对cookie做的扩展, 该值指定cookie是否可通过客户端脚本访问。
如果在Cookie中没有设置Http Only属性为true, 可能导致Cookie被窃取。
窃取的Cookie可以包含标识站点用户的敏感信息, 如ASPNET会话ID或Forms身份验证票证,
攻击者可以重播窃取的Cookie, 以便伪装成用户或获取敏感信息, 进行跨站脚本攻击等。
Cookie的作用域
Domain和Path标识定义了Cookie的作用域:即Cookie应该发送给哪些URL,Domain标识指定了哪些主机可以接受Cookie。
如果不指定, 默认为当前主机(不包含子域名)
如果指定了Domain, 则一般包含子域名
例如
如果设置Domain=mozilla.org, 则Cookie也包含在子域名中(如developer.mozilla.org)
设置Path=/docs, 则以下地址都会匹配:
/docs
/docs/Web/
/docs/Web/HTTP
/docs/Web/
/docs/Web/HTTP
Session是什么
客户端请求服务端, 服务端会为这次请求开辟一块内存空间, 这个对象便是Session对象
存储结构为ConcurrentHashMap
Session弥补了HTTP无状态特性, 服务器可以利用Session存储客户端在同一个会话期间的一些操作记录。
Cookie和Session的目的
HTTP协议是一种无状态协议, 即每次服务端接收到客户端的请求时, 都是一个全新的请求, 服务器并不知道客户端的历史请求记录;
Session和Cookie的主要目的就是为了弥补HTTP的无状态特性。
Session如何判断是否是同一会话
服务器第一次接收到请求时, 开辟了一块Session空间(创建了Session对象)
同时生成一个sessionld, 并通过响应头的Set-Cookie:JSESSIONID=XXXXXXX命令, 向客户端发送要求设置Cookie的响应;
客户端收到响应后, 在本机客户端设置了一个JSESSIONID=XXX XXXX的Cookie信息,
该Cookie的过期时间为浏览器会话结束;
Session如何判断是否是同一会话
接下来客户端每次向同一个网站发送请求时, 请求头都会带上该Cookie信息(包含sessionld) ,
然后, 服务器通过读取请求头中的Cookie信息, 获取名称为JSESSIONID的值, 得到此次请求的sessionld。
Session的缺点
Session机制有个缺点, 比如A服务器存储了Session, 就是做了负载均衡后, 假如一段时间内A的访
问量激增, 会转发到B进行访问, 但是B服务器并没有存储A的Session, 会导致Session的失效
问量激增, 会转发到B进行访问, 但是B服务器并没有存储A的Session, 会导致Session的失效
分布式Session问题
JWT和Session Cookies的对比
会话Cookie(Session Cookies)介绍
Session Cookies
Session Cookies也称为会话Cookies
上面的示例创建的是会话Cookie,
会话Cookie有个特征, 客户端关闭时,Cookie会删除, 因为它没有指定Expires或Max-Age指令。
但是, Web浏览器可能会使用会话还原, 这会使大多数会话Cookie保持永久状态, 就像从未关闭过浏览器一样
如果Cookie不包含到期日期, 则将其视为会话Cookie。
会话Cookie存储在内存中, 永远不会写入磁盘, 当浏览器关闭时, 此后Cookie将永久丢失。
以登录逻辑为例(图解会话Cookie)
在Session Cookies中, 用户的登录状态会保存在服务器的内存中,
当用户登录时, Session就被服务端安全的创建。
在每次请求时, 服务器都会从会话Cookie中读取Sessionld,
如果服务端的数据和读取的Sessionld相同,那么服务器就会发送响应给浏览器,允许用户登录。
图解会话Cookie
以登录逻辑为例(图解会话Cookie)
JWT(Json Web Tokens)介绍
什么是Json Web Tokens(JWT)
JSON Web Token
简称JWT
它和Session都可以为网站提供用户的身份认证, 但是它们不是一回事。
Json Web Token的简称就是JWT, 通常可以称为Json令牌。
它是RFC 7519中定义的用于安全的将信息作为Json对象进行传输的一种形式。
JWT中存储的信息是经过数字签名的, 因此可以被信任和理解。
可以使用HMAC算法或使用RSA/ECDSA的公用/专用密钥对JWT进行签名,
使用JWT主要用来下面两点
认证(Authorization)
这是使用JWT最常见的一种情况
一旦用户登录, 后面每个请求都会包含JWT, 从而允许用户访问该令牌所允许的路由、服务和资源。
单点登录是当今广泛使用JWT的一项功能, 因为它的开销很小,
信息交换(Information Exchange)
JWT是能够安全传输信息的一种方式。
通过使用公钥/私钥对JWT进行签名认证。
此外, 由于签名是使用head和payload计算的, 因此你还可以验证内容是否道到篡改。
JWT的格式(JWT的组成和格式是什么?)
Header
Header是JWT的标头
它通常由两部分组成
令牌的类型(即JWT)
使用的签名法
例如HMAC SHA 256或RSA
图解JWT的Header
图解JWT的Header
指定了令牌的类型和签名算法后, Json块被Base64Url编码形成JWT的第一部分。
PayLoad
Token的第二部分是Payload, Payload中包含一个声明。
声明是有关实体(通常是用户) 和其他数据的声明。
共有三种类型的声明
registered声明
包含一组建议使用的预定义声明
registered声明主要包括
registered声明主要包括
public声明
公共的声明, 可以添加任何的信息
一般添加用户的相关信息或其他业务需要的必要信息,
但不建议添加敏感信息,因为该部分在客户端可解密。
private声明
自定义声明
旨在在同意使用它们的各方之间共享信息,
既不是注册声明也不是公共声明
图解JWT的PayLoad
图解JWT的PayLoad
然后payload Json块会被Base64Url编码形成JWT的第二部分。
Signature
JWT的第三部分是一个签证信息
这个签证信息由三部分组成
header(base 64后的)
payload(base 64后的)
secret
比如需要HMACSHA256算法进行签名
HMACSHA256算法进行签名
签名的作用
用于验证消息在此过程中没有更改
并且对于使用私钥进行签名的令牌,它还可以验证JWT的发送者的真实身份
下面是一个完整的JWT示例
拼凑在一起
现在把上面的三个由点分隔的Base64-URL字符串部分组成在一起(每个部分用.进行分割),
这个字符串可以在HTML和HTTP环境中轻松传递这些字符串,
解读JWT示例
它对header和payload进行缩码, 然后使用signature进行签名
对header和payload进行缩码, 然后使用signature进行签名
解读JWT示例
如果想自己测试编写的话, 可以访问JWT官网https://jwt.io/#debuggor-io
一个非常简单的JWT组成会是下面这样
一个非常简单的JWT组成
JWT和Session Cookies的相同之处
对用户进行身份验证
用来在用户单击进入不同页面时以及登陆网站或应用程序后,进行身份验证
如果没有这两者, 那你可能需要在每个页面切换时都需要进行登录了。
因为HTTP是一个无状态的协议。
这也就意味着当你访问某个网页,然后单击同一站点上的另一个页面时,服务器的内存中将不会记住你之前的操作。
图解
当你访问某个网页,然后单击同一站点上的另一个页面时,服务器的内存中将不会记住你之前的操作
因此, 如果你登录并访问了你有权访问的另一个页面, 由于HTTP不会记录你刚刚登录的信息, 因此你将再次登录
JWT和Session Cookies就是用来处理在不同页面之间切换, 保存用户登录信息的机制。
这两种技术都是用来保存你的登录状态,能够让你在浏览任意受密码保护的网站。
通过在每次产生新的请求时,对用户数据进行身份验证,来解决此问题。
它们能够支持你在发送不同请求之间, 记录并验证你的登录状态的一种机制。
JWT和Session不同之处的研究
JWT和Session Cookies的不同
JWT和Session Cookies都提供安全的用户身份验证, 但是它们有以下几点不同
密码签名
JWT具有加密签名, 而Session Cookies则没有。
JSON是无状态的
JWT是无状态的, 因为声明被存储在客户端, 而不是服务端内存中。
身份验证可以在本地进行,而不是在请求必须通过服务器数据库或类似位置中进行。
这意味着可以对用户进行多次身份验证,而无需与站点或应用程序的数据库进行通信,也无需在此过程中消耗大量资源。
可扩展性
Session Cookies是存储在服务器内存中, 这就意味着如果网站或者应用很大的情况下会耗费大量的资源.
由于JWT是无状态的, 在许多情况下, 它们可以节省服务器资源。
因此JWT要比SessionCookies具有更强的可扩展性.
JWT支持跨域认证
Session Cookies只能用在单个节点的域或者它的子域中有效。
如果它们尝试通过第三个节点访问,就会被禁止。
如果你希望自己的网站和其他站点建立安全连接时,这是一个问题。
使用JWT可以解决这个问题, 使用JWT能够通过多个节点进行用户认证, 也就是常说的跨域认证。
JWT和Session Cookies的选型
对于只需要登录用户并访问存储在站点数据库中的一些信息的中小型网站来说, Session Cookies通常就能满足。
如果你有企业级站点,应用程序或附近的站点,并且需要处理大量的请求,尤其是第三方或很多第三方(包括位于不同域的API) , 则JWT显然更适合。
如何禁用Cookies后, 使用Session
如果禁用了Cookies, 服务器仍会将session ld以cookie的方式发送给浏览器,
但是, 浏览器不再保存这个cookie(即session ld) 了。
如果想要继续使用session, 需要采用URL重写的方式来实现
https://blog.csdn.net/Future1994/article/details/111131262
https://blog.51cto.com/NIO4444/3838554
怎么解决HTTP是无状态协议的问题?
什么是无状态协议
无状态协议(Stateless Protocol)
就是指浏览器对于事务的处理没有记忆能力
举例说明:
比如客户请求获得网页之后关闭浏览器,然后再次启动浏览器,登录该网站,但是服务器并不知道客户关闭了一次浏览器。
比如客户请求获得网页之后关闭浏览器,然后再次启动浏览器,登录该网站,但是服务器并不知道客户关闭了一次浏览器。
HTTP是一种无状态协议
HTTP就是一种无状态的协议
它对用户的操作没有记忆能力
使用Cookie的机制
原来如此
可能大多数用户不相信, 他可能觉得每次输入用户名和密码登陆一个网站后, 下次登陆就不再重新输入用户名和密码了。
这其实不是HTTP做的事情, 起作用的是一个叫做小甜饼(Cookie) 的机制。
它能够让浏览器具有记忆能力。
如何查看Cookie数据 ?
如果你的浏览器允许cookie, 查看方式chrome://settings/content/cookies
chrome://settings/content/cookies
也就说明你的记忆芯片通电了
图解会话Cookie的过程
图解会话Cookie的过程
图解会话Cookie的实现原理、
会话Cookie的实现原理、
当你想服务端发送请求时,服务端会给你发送一个认证信息,
服务器第一次接收到请求时, 开辟了一块Session空间(创建了Session对象) , 同时生成一个sessionld,
并通过响应头的Set-Cookie:JSESSIONID=XXXXXXX命令, 向客户端发送要求设置Cookie的响应;
客户端收到响应后, 在本机客户端设置了一个JSESSIONID=XXXXXXX的Cookie信息, 该Cookie的过期时间为浏览器会话结束
接下来客户端每次向同一个网站发送请求时, 请求头都会带上该Cookie信息(包含sessionld)
然后, 服务器通过读取请求头中的Cookie信息, 获取名称为JSESSIONID的值, 得到此次请求的sessionld。
这样, 你的浏览器才具有了记忆能力。
使用JWT机制
它也是能够让你的浏览器具有记忆能力的一种机制。
与Cookie不同, JWT是保存在客户端的信息, 它广泛的应用于单点登录的情况。
JWT具有两个特点
JWT的Cookie信息存储在客户端, 而不是服务端内存中
JWT直接本地进行验证就可以, 验证完毕后, 这个Token就会在Session中随请求一起发送到服务器
通过这种方式, 可以节省服务器资源, 并且token可以进行多次验证.
JWT支持跨域认证
Cookies只能用在单个节点的域或者它的子域中有效。
如果它们尝试通过第三个节点访问, 就会被禁止。
使用JWT可以解决这个问题, 使用JWT能够通过多个节点进行用户认证
也就是常说的跨域认证
认识与探究HTTPS
HTTPS解决了什么问题
一个新技术的出现必定是为了解决某种问题的, 那么HTTPS解决了HTTP的什么问题呢?
一个简单的回答可能会是HTTP它不安全。
HTTP一般是明文传输, 很容易被攻击者窃取重要信息, 鉴于此, HTTPS应运而生。
HTTP不安全的原因
由于HTTP天生明文传输的特性, 在HTTP的传输过程中, 任何人都有可能从中截获、修改或者伪造请求发送, 所以可以认为HTTP是不安全的;
在HTTP的传输过程中,不会验证通信方的身份, 因此HTTP信息交换的双方可能会遭到伪装, 也就是没有用户验证;
在HTTP的传输过程中, 接收方和发送方并不会验证报文的完整性,
综上, 为了结局上述问题,HTTPS应用而生。
为了结局上述问题,HTTPS应用而生
HTTP和HTTPS的主要区别是什么呢?
地址栏的显示
最简单的, HTTP在地址栏上的协议是以http://开头, 而HTTPS在地址栏上的协议是以https://开头
http://www.cxuanblog.com/
https://www.cxuanblag.com/
https://www.cxuanblag.com/
图解地址栏的显示
图解地址栏的显示
安全性
HTTP是未经安全加密的协议, 它的传输过程容易被攻击者监听、数据容易被窃取、发送方和接收方容易被伪造;
而HTTPS是安全的协议, 它通过密钥交换算法-签名算法-对称加密算法-摘要算法能够解决上面这些问题。
HTTPS是以安全为目标的HTTP通道
HTTPS在HTTP的基础上,通过传输加密和身份认证,保证了传输过程的安全性。
HTTPS在HTTP的基础上增加了SSL层, 也就是说HTTPS=HTTP+SSL。
HTTPS协议提供了三个关键的指标
加密(Encryption)
HTTPS通过对数据加密来使其免受窃听者对数据的监听
这就意味着当用户在浏览网站时,没有人能够
监听他和网站之间的信息交换
跟踪用户的活动,访问记录等
数据一致性(Data integrity)
数据在传输的过程中不会被窃听者所修改,
用户发送的数据会完整的传输到服务端,保证用户发的是什么,服务器接收的就是什么
身份认证(Authentication)
指确认对方的真实身份, 也就是证明你是你(可以比作人脸识别),它可以防止中间人攻击井建立用户信任。
有了上面三个关键指标的保证,用户就可以和服务器进行安全的交换信息了
怎么知道网站是用HTTPS的还是HTTP的呢?
图解怎么知道网站是用HTTPS的还是HTTP的呢?
HTTPS是如何定义的 ? HTTPS协议介绍
HTTPS的全称是Hypertext Transfer Protocol Secure
HTTPS的全称为(HyperText Transfer Protocol over Secure Socket Layer) , 全称有点长,
从名称可以看出,HTTPS要比HTTPS多了secure安全性这个概念
它用来在计算机网络上的两个端系统之间进行安全的交换信息(secure communication)
它相当于在HTTP的基础上加了一个Secure安全的词眼
HTTPS是一个在计算机世界里专门在两点之间【安全的】传输文字、图片、音频、视频等超文本数据的约定和规范。
实际上, HTTPS并不是一个新的应用层协议, 它其实就是HTTP+TLS/SSL协议组合而成, 而安全性的保证正是TLS/SSL所做的工作。
HTTPS就是身披了一层SSL的HTTP。
HTTPS协议其实非常简单
RFC文档很小, 只有短短的7页, 里面规定了新的协议名, 默认口号443
至于其他的应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用HTTP,没有任何新的东西。
也就是说, 除了协议名称和默认端口号外{HTTP默认端口80) ,
实际上, HTTPS并不是一个新的应用层协议, 它其实就是HTTP+TLS/SSL协议组合而成, 而安全性的保证正是TLS/SSL所做的工作。
HTTPS协议在语法、语义上和HTTP一样, HTTP有的, HTTPS也照单全收。
谁来保证HTTPS的安全性呢?
HTTPS是HTTP协议的一种扩展,它本身并不保传输的证安全性, 那么谁来保证安全性呢?
在HTTPS中, 使用两种技术对通信协议进行加密。
传输层安全性(TLS)
安全套接字层(SSL)
关键在于这个S也就是SSL/TLS.
也就是HTTP+SSL(TLS) =HTTPS。
HTTP+SSL(TLS) =HTTPS。
SSL/TLS介绍
认识SSL/TLS
TLS (Transport Layer Security) 是SSL(Secure Socket Layer) 的后续版本
它们是用于在互联网两台计算机之间用于身份验证和加密的一种协议。
注意:在互联网中,很多名称都可以进行互换。
一些在线业务(比如在线支付)最重要的一个步骤是创建一个值得信赖的交易环境,能够让客户安心的进行交易, SSL/TLS就保证了这一点,
SSL/TLS工作原理
SSL/TLS通过将称为X.509证书的数字文档,将网站和公司的实体信息,绑定到加密密钥来进行工作。
每一个密钥对(key pairs) 都有一个私有密钥(private key) 和公有密钥(publickey)
私有密钥是独有的, 一般位于服务器上, 用于解密由公共密钥加密过的信息
公有密钥是公有的,与服务器进行交互的每个人都可以持有公有密钥,用公钥加密的信息只能由私有密钥来解密。
X.509介绍
什么是X.509
X.509是公开密钥证书的标准格式,
这个文档将加密密钥与(个人或组织)进行安全的关联。
X.509主要应用
SSL/TLS和HTTPS用于经过身份验证和加密的Web浏览
通过S/MIME协议签名和加密的电子邮件
代码签名
它指的是使用数字证书对软件应用程序进行签名以安全分发和安装的过程。
使用数字证书对软件应用程序进行签名以安全分发和安装的过程
通过使用由知名公共证书颁发机构(例如SSL.com)颁发的证书对软件进行数字签名,
开发人员
可以向最终用户保证他们希望安装的软件是由已知且受信任的开发人员发布;并且签名后未被篡
改或损害.
文档签名
客户端认证
政府签发的电子身份证
(详见https://www.ssl.com/article/pki-and-digital-ceriicates-for-government/)
HTTPS的内核是HTTP
HTTPS并不是一项新的应用层协议, 只是HTTP通信接口部分由SSL和TLS替代而已。
通常情况下, HTTP会先直接和TCP进行通信。
在使用SSL的HTTPS后, 则会先演变为和SSL进行通信, 然后再由SSL和TCP进行通信,
也就是说, HTTPS就是身披了一层SSL的HTTP.
HTTPS就是身披了一层SSL的HTTP.
SSL是一个独立的协议, 不只有HTTP可以使用 。
其他应用层协议也可以使用, 比如SMTP(电子邮件协议) 、Telnet(远程录协议) 等都可以使用
HTTPS的握手过程
探讨HTTPS的握手过程, 其实就是SSL/TLS的握手过程。
SSL介绍
SSL即安全套接字层, 它在OSI七层网络模型中处于第五层(5-会话层)
SSL在1999年被IETF(互联网工程组) 更名为TLS, 即传输安全层,
直到现在, TLS一共出现过三个版本, 1.1、1.2和1.3, 目前最广泛使用的是1.2,
所以接下来的探讨都是基于TLS 1.2的版本上的。
TLS介绍
TLS用于两个通信应用程序之间提供保密性和数据完整性
TLS旨在为Internet提供通信安全的加密协议。
SSL/TLS的握手过程
TLS握手是启动和使用TLS加密的通信会话的过程。
在TLS握手期间, Internet中的通信双方会彼此交换信息, 验证密码套件, 交换会话密钥。
每当用户通过HTTPS导航到具体的网站并发送请求时, 就会进行TLS握手。
除此之外, 每当其他任何通信使用HTTPS(包括API调用和在HTTPS上查询DNS) 时, 也会发生TLS握手,
TLS具体的握手过程会根据所使用的密钥交换算法的类型和双方支持的密码套件而不同
以RSA非对称加密为例,图解讨论SSL/TLS的握手过程
整个TLS通信流程图
以RSA非对称加密为例,讨论SSL/TLS的握手过程
在进行通信前, 首先会进行HTTP的三次握手, 握手完成后, 再进行TLS的握手过程
Client Hello
客户端通过向服务器发送hello消息来发起握手过程。
这条消息包含了
客户端支持的TLS版本号(TLS 1.0、TLS 1.2、TLS 1.3)
客户端支持的密码套件
以及一串客户端随机数
Server Hello
在客户端发送hello消息后, 服务器会发送一条消息,
这条消息包含了
服务器的SSL证书
服务器选择的密码套件
服务器生成的随机数
认证(Authentication)
客户端的证书颁发机构会认证SSL证书, 然后发送Certificate报文,报文中包含公开密钥证书。
最后服务器发送Server Hello Done作为hello请求的响应。
第一部分握手阶段结束。
加密阶段
在第一个阶段握手完成后, 客户端会发送ClientKeyExchange作为响应
这个响应中包含了一种称为The premaster secret的密钥字符串
这个字符串就是使用上面公开密钥证书进行加密的字符串
随后客户端会发送ChangeCipherSpec, 告诉服务端使用私钥解密这个premaster secret的字符串, 然后客户端发送Finished告诉服务端自己发送完成了。
Session key其实就是用公钥证书加密的公钥。
实现了安全的非对称加密:
然后, 服务器再发送ChangeCipherSpec和Finished告诉客户端解密完成
至此实现了RSA的非对称加密
TLS的组成
由几个子协议组成
记录协议
握手协议
警告协议
变更密码规范协议
扩展协议
综合使用了许多密码学前沿技术
对称加密
非对称加密
身份认证
TLS的TLS的结构与解析
(可以
参考https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml)
TLS的结构与解析
使用ECD HE进行密钥交换
使用ECDSA进行签名和认证
然后使用AES作为对称加密算法,密钥的长度是256位
使用GCM作为分组模式
最后使用SHA 384作为摘要算法
因为TLS的密码套件比较规范, 基本格式就是由各个算法组成而成的一个密码串,有时候还有分组模式
密钥交换算法-签名算法-对称加密算法-【分组模式】-摘要算法
密码学基础概念
明文
明文(Plaintext)
一般认为明文是有意义的字符或者比特集, 或者是通过某种公开编码就能获得的消息。
明文通常用m或p表示
密文
密文(Ciphertext)
对明文进行某种加密后就变成了密文
加密
加密(Encrypt)
把原始的信息(明文) 转换为密文的信息变换过程
解密
解密(Decrypt)
把已经加密的信息恢复成明文的过程。
TLS在根本上使用两种加密形式
对称加密
是什么?
对称加密(Symmetrical Encryption)
指加密和解密时使用的密钥都是同样的密钥
只要保证了密钥的安全性,那么整个通信过程也就是具有了机密性,
图解对称加密
图解对称加密
TLS里面有比较多的加密算法可供使用
比如DES、3DES、AES、ChaCha20、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK等
目前最常用的是
AES-128
AES-192
AES-256
ChaCha20
常用的对称加密算法
AES
AES的全称是Advanced EncryptionStandard(高级加密标准)
它是DES算法的替代者
安全强度很高, 性能也很好,是应用最广泛的对称加密算法。
DES
全称是Data Encryption Standard(数据加密标准) ,
它是用于数字数据加密的对称密钥算法,
尽管其56位的短密钥长度使它对于现代应用程序来说太不安全了,但它在加密技术的发展中具有很大的影响力。
3DES
从原始数据加密标准(DES) 衍生过来的加密算法
它在90年代后变得很重要, 但是后面由于更加高级的算法出现, 3DES变得不再重要。
ChaCha20
是Google设计的另一种加密算法,
密钥长度固定为256位, 纯软件运行性能要超过AES
曾经在移动客户端上比较流行, 但ARMv8之后也加入了AES硬件优化,
所以现在不再具有明显的优势,但仍然算得上是一个不错算法。
对称加密存在风险
对称加密的加密方和解密方都使用同一个密钥
也就是说,加密方必须对原始数据进行加密,然后再把密钥交给解密方进行解密,然后才能解密数据
这就会造成什么问题?
这就好比《小兵张嘎》去送信(信已经被加密过),但是嘎子还拿着解密的密码
那嘎子要是在途中被鬼子发现了,那这信可就是被完全的暴露了。
所以,对称加密存在风险。
加密分组
对称加密算法还有一个分组模式的概念
对于GCM分组模式, 只有和AES, CAMELLIA和ARIA搭配使用
而AES显然是最受欢迎和部署最广泛的选择, 它可以让算法用固定长度的密钥加密任意长度的明文。
最早有ECB、CBC、CFB、OFB等几种分组模式, 但都陆续被发现有安全漏洞, 所以现在基本都不怎么用了
最新的分组模式被称为AEAD(Authenticated Encryption with AssociatedData) ,
在加密的同时增加了认证的功能,
常用的是GCM、CCM和Poly 1305
举例:
比如ECDHE_ECDSA_AES128_GCM_SHA256
AES128表示的是具有128位密钥, AES256将表示256位密钥。
GCM表示具有128位块的分组密码的现代认证的关联数据加密(AEAD) 操作模式
TLS的结构与解析
使用ECD HE进行密钥交换
使用ECDSA进行签名和认证
然后使用AES作为对称加密算法,密钥的长度是256位
使用GCM作为分组模式
最后使用SHA 384作为摘要算法
非对称加密
是什么?
非对称加密(Asymmetrical Encryption)
也被称为公钥加密
相对于对称加密来说, 非对称加密是一种新的改良加密方式
密钥通过网络传输交换,它能够确保及时密钥被拦截,也不会暴露数据信息。
非对称加密中有两个密钥
一个是公钥
公钥进行加密
公开密钥可供任何人使用
一个是私钥
私钥进行解密
私钥只有你自己能够知道
图解非对称加密
图解非对称加密
原理说明
使用公钥加密的文本,只能使用私钥解密,同时,使用私钥加密的文本也可以使用公钥解密。
公钥不需要具有安全性,因为公钥需要在网络间进行传输
非对称加密可以解决密钥交换的问题,网站保管私钥,在网上任意分发公钥
你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。
而黑客因为没有私钥,所以就无法破解密文。
非对称加密算法的设计要比对称算法难得多
常见的比如DH、DSA、RSA、ECC等。
其中R5A加密算法是最重要的、最出名的一个了,
例如DHE_RSA_CAMELLIA128_GCM-SHA256
它的安全性基于整数分解
使用两个超大素数的乘积作为生成密钥的材料
想要从公钥推算出私钥是非常困难的
常用的非对称加密算法
R5A
它的安全性基于整数分解
使用两个超大素数的乘积作为生成密钥的材料
想要从公钥推算出私钥是非常困难的
ECC
ECC(Elliptic Curve Cryptography)
也是非对称加密算法的一种
它基于椭圆曲线岛散对数的数学难题
使用特定的曲线方程和基点生成公钥和私钥
ECDHE用于密钥交换
ECDSA用于数字签名
TLS是使用混合加密方式来实现机密性
TLS是使用对称加密和非对称加密的混合加密方式来实现机密性。
RSA的运算速度非常慢, 而AES的加密速度比较快, 而TLS正是使用了这种混合加密方式。
TLS混合加密原理
在通信刚开始时,使用非对称算法, 比如RSA、ECDHE,首先解决密钥交换的问题
然后用随机数产生对称算法使用的会话密钥(session key) , 再用公钥加密, 对方拿到密文后用私钥解密, 取出会话密钥。
这样,双方就实现了对称密钥的安全交换。
图解混合加密过程
图解混合加密过程
现在使用混合加密的方式实现了机密性,是不是就能够安全的传输数据了呢?
还不够,在机密性的基础上还要加上完整性、身份认证的特性,才能实现真正的安全。
而实现完整性的主要手段是摘要算法(Digest Algorithm)
TLS是使用摘要算法来实现完整性
如何实现完整性呢?
在TLS中, 实现完整性的手段主要是摘要算法(Digest Algorithm)
可以把摘要算法理解成一种特殊的压缩算法,它能够把任意长度的数据压缩成一种固定长度的字符串。
这就好像是给数据加了一把锁
图解MD5加密
图解MD5加密
MD5介绍
MD5的全称是Message Digest Algorithm5
它是属于密码哈希算法(cryptographic hash algorithm) 的一种
MD5可用于从任意长度的字符串创建128位字符串值。
MD5使用场景
尽管MD5存在不安全因素,但是仍然沿用至今。
MD5最常用于验证文件的完整性。
但是, 它还用于其他安全协议和应用程序中, 例如
IPSec
(英语:Internet Protocol Security,缩写为IPsec),
是一个协议包
通过对IP协议的分组进行加密和认证来保护IP协议的网络传输协议簇
网络传输协议簇(一些相互关联的协议的集合)。
SSL
SSL(Secure Sockets Layer 安全套接层)
及其继任者传输层安全(Transport Layer Security,TLS)
是为网络通信提供安全及数据完整性的一种安全协议。
TLS与SSL在传输层对网络连接进行加密。
SSH
增强MD5算法
向明文加盐值
多次应用哈希函数
什么是加盐?
在密码学中,盐就是一项随机数据,用作哈希数据
密码或密码的单向函数的附加输入。
盐用于保护存储中的密码
例如
盐用于保护存储中的密码
什么是单向?
这种算法没有密钥可以进行解密,只能进行单向加密
加密后的数据无法解密,不能逆推出原文。
SHA-2与SHA-2系列介绍
除了常用的MD 5是加密算法外, SHA-1(Secure Hash Algorithm 1) 也是一种常用的加密算法
为什么不是SHA-1 ?
目前TLS推荐使用的是SHA-1的后继者:SHA-2
不过SHA-1也是不安全的加密算法, 在TLS里面被禁止使用
SHA-2是什么?
SHA-2的全称是Secure Hash Algorithm 2
它在2001年被推出
它在SHA-1的基础上做了重大的修改
SHA-2系列包含六个哈希函数
其摘要(哈希值) 分别为224、256、384或512位:SHA-224, SHA-256, SHA-384, SHA-512
分别能够生成28字节、32字节、48字节、64字节的摘要
SHA-2还是不够安全
有了SHA-2的保护, 就能够实现数据的完整性,
哪怕你在文件中改变一个标点符号, 增加一个空格,生成的文件摘要也会完全不同
不过SHA-2是基于明文的加密方式, 还是不够安全, 那应该用什么呢?
HMAC 和MAC介绍
什么是MAC
MAC的全称是message authentication code
它通过MAC算法从消息和密钥生成, MAC值允许验证者(也拥有秘密密钥)检测到消息内容的任何更改,从而保护了消息的数据完整性。
什么是HMAC
HMAC是MAC更进一步的拓展
它是使用MAC值+Hash值的组合方式
HMAC的计算中可以使用任何加密哈希函数, 例如SHA-256等。
图解HMAC工作流程
图解HMAC工作流程
安全性更高的加密方式是使用HMAC
TLS是使用改善后的非对称解密过程,实现身份认证
背景
我们在向服务器发送数据的过程中,黑客(攻击者)有可能伪装成任何一方来窃取信息,
它可以伪装成你,来向服务器发送信息,
也可以伪装称为服务器,接受你发送的信息
那么怎么解决这个问题呢?
如何确定你自己的唯一性呢?
把公钥加密和私钥解密的顺序调换一下,变成私钥加密,公钥解密。
使用私钥再加上摘要算法,就能够实现数字签名,从而实现认证。
图解身份认证过程
子主题
TLS中关于数字签名的认证问题
做到了以上,是不是就安全了呢?
到现在,综合使用对称加密、非对称加密和摘要算法,我们已经实现了加密、数据认证、认证,
那么是不是就安全了呢?
非也,这里还存在一个数字签名的认证问题。
为什么需要引入CA ?
因为私钥是是自己的,公钥是谁都可以发布
所以必须发布经过认证的公钥,才能解决公钥的信任问题
CA是什么?
CA的全称是Certificate Authority
证书认证机构
你必须让CA颁布具有认证过的公钥,才能解决公钥的信任问题。
全世界具有认证的CA就几家,分别颁布了DV、OV、EV三种,区别在于可信程度。
CA中三种不同的可信程度
DV
DV是最低的,只是域名级别的可信
OV
介于两者之间
EV
EV是最高的,经过了法律和审计的严格核查
可以证明网站拥有者的身份
(在浏览器地址栏会显示出公司的名字,例如Apple、GitHub的网站)
图解CA中的层级结构
不同的信任等级的机构一起形成了层级关系
简述CA工作流程
通常情况下, 数字证书的申请人将生成的密钥对。
密钥对由三者组成
私钥
公钥
证书签名请求(CSR)
CSR是什么?
一个编码的文本文件
其中包含公钥和其他将包含在证书中的信息
例如域名,组织,电子邮件地址等
密钥对和CSR生成通常在将要安装证书的服务器上完成, 并且CSR中包含的信息类型取决于证书的验证级别。
与公钥不同,申请人的私钥是安全的,永远不要向CA(或其他任何人)展示。
生成CSR后, 申请人将其发送给CA, CA会验证其包含的信息是否正确
如果正确, 则使用颁发的私钥对证书进行数字签名,然后将其发送给申请人
图解CA工作流程
图解CA工作流程
0 条评论
下一页