震惊 HTTP 在疫情期间把我吓得不敢出门了(二)

简介: 这是 HTTP 系列的第三篇文章,此篇文章为 HTTP 的进阶文章。 在前面两篇文章中我们讲述了 HTTP 的入门,HTTP 所有常用标头的概述,这篇文章我们来聊一下 HTTP 的一些 黑科技。

代理认证

由于资源认证和代理认证可以共存,因此需要不同的头和状态码,在代理的情况下,会返回状态码 407(需要代理认证)Proxy-Authenticate 响应头包含至少一个适用于代理的情况,Proxy-Authorization请求头用于将证书提供给代理服务器。下面分别来认识一下这两个标头

Proxy-Authenticate

HTTP Proxy-Authenticate 响应标头定义了身份验证方法,应使用该身份验证方法来访问代理服务器后面的资源。它将请求认证到代理服务器,从而允许它进一步发送请求。例如

Proxy-Authenticate: Basic
Proxy-Authenticate: Basic realm="Access to the internal site"

Proxy-Authorization

这个 HTTP 请求标头和上面的 Proxy-Authenticate 拼接很相似,但是概念不同,这个标头用于向代理服务器提供凭据,例如

Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

下面是代理服务器的请求/响应认证过程

微信图片_20220412195627.jpg

这个过程和通用的过程类似,我们就不再详细展开描述了。

禁止访问

如果代理服务器收到的有效凭据不足以获取对给定资源的访问权限,则服务器应使用403 Forbidden状态代码进行响应。与 401 Unauthorized407 Proxy Authorization Required 不同,该用户无法进行身份验证。

WWW-Authenticate 和 Proxy-Authenticate 头

WWW-AuthenticateProxy-Authenticate 响应头定义了获得对资源访问权限的身份验证方法。他们需要指定使用哪种身份验证方案,以便希望授权的客户端知道如何提供凭据。它们的一般表示形式如下

WWW-Authenticate:  realm=

Proxy-Authenticate: realm=

我想你从上面看到这里一定会好奇 realm是什么东西,现在就来解释下。

  • 是认证协议,Basic 是下面协议中最普遍使用的

RFC 7617 中定义了Basic HTT P身份验证方案,该方案将凭据作为用户ID /密码对传输,并使用 base64 进行编码。(感兴趣的同学可以看看 https://tools.ietf.org/html/rfc7617)

其他的认证协议主要有

认证协议 参考来源
Basic 查阅 RFC 7617,base64编码的凭据
Bearer 查阅 RFC 6750,承载令牌来访问受 OAuth 2.0保护的资源
Digest 查阅 RFC 7616,Firefox仅支持md5哈希,请参见错误bug 472823以获得SHA加密支持
HOBA 查阅 RFC 7486
Mutual 查阅 RFC 8120
AWS4-HMAC-SHA256 查阅 AWS docs
  • realm 用于描述保护区或指示保护范围,这可能是诸如 Access to the staging site(访问登陆站点) 或者类似的,这样用户就可以知道他们要访问哪个区域。

Authorization 和 Proxy-Authorization 标头

Authorization 和 Proxy-Authorization 请求标头包含用于通过代理服务器对用户代理进行身份验证的凭据。在此,再次需要类型,其后是凭据,取决于使用哪种身份验证方案,可以对凭据进行编码或加密。一般表示如下

Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Proxy-Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

HTTP 缓存

通过把请求/响应缓存起来有助于提升系统的性能,Web 缓存减少了延迟和网络传输量,因此减少资源获取锁需要的时间。由于链路漫长,网络时延不可控,浏览器使用 HTTP 获取资源的成本较高。所以,非常有必要把数据缓存起来,下次再请求的时候尽可能地复用。当 Web 缓存在其存储中具有请求的资源时,它将拦截该请求并直接返回资源,而不是到达源服务器重新下载并获取。这样做可以实现两个小目标

  • 减轻服务器负载
  • 提升系统性能

下面我们就一起来探讨一下 HTTP 缓存都有哪些

不同类型的缓存

HTTP 缓存有几种不同的类型,这些可以分为两个主要类别:私有缓存共享缓存

  • 共享缓存:共享缓存是一种缓存,它可以存储多个用户重复使用的请求/响应。
  • 私有缓存:私有缓存也称为专用缓存,它只适用于单个用户。
  • 不缓存过期资源:所有的请求都会直接到达服务器,由服务器来下载资源并返回。

我们主要探讨浏览器缓存代理缓存,但真实情况不只有这两种缓存,还有网关缓存,CDN,反向代理缓存和负载平衡器,把它们部署在 Web 服务器上,可以提高网站和 Web 应用程序的可靠性,性能和可伸缩性。

不缓存过期资源

不缓存过期资源即浏览器和代理不会缓存过期资源,客户端发起的请求会直接到达服务器,可以使用 no-cache 标头代表不缓存过期资源。

微信图片_20220412195633.jpg

no-cache 属于 Cache-Control 通用标头,其一般的表示方法如下

Cache-Control: no-cache

也可以使用 max-age = 0 来实现不缓存的效果。

Cache-Control: max-age=0

私有缓存

私有缓存只用来缓存单个用户,你可能在浏览器设置中看到了 缓存,浏览器缓存包含服务器通过 HTTP 下载下来的所有文档。这个高速缓存用于使访问的文档可以进行前进/后退,保存操作而无需重新发送请求到源服务器。

微信图片_20220412195636.jpg

可以使用 private 来实现私有缓存,这与 public 的用法相反,缓存服务器只对特定的客户端进行缓存,其他客户端发送过来的请求,缓存服务器则不会返回缓存。它的一般表示方法如下

Cache-Control: private

共享缓存

共享缓存是一种用于存储要由多个用户重用的响应缓存。共享缓存一般使用 public 来表示,public 属性只出现在客户端响应中,表示响应可以被任何缓存所缓存。一般表示方法如下

Cache-Control: public

微信图片_20220412195640.jpg

缓存控制

HTTP/1.1 中的 Cache-Control 常规标头字段用于执行缓存控制,使用此标头可通过其提供的各种指令来定义缓存策略。下面我们依次介绍一下这些属性

不缓存

no-store 才是真正意义上的不缓存,每次服务器接受到客户端的请求后,都会返回最新的资源给客户端。

Cache-Control: no-store

缓存但需要验证

同上面的 不缓存过期资源

私有和共享缓存

同上

缓存过期

缓存中一个很重要的指令就是max-age,这是资源被视为新鲜的最长时间 ,与 Expires 相反,此指令是相对于请求时间的。对于应用程序中不会更改的文件,通常可以添加主动缓存。下面是 mag-age 的表示

Cache-Control: max-age=31536000

缓存验证

must-revalidate 表示缓存必须在使用之前验证过时资源的状态,并且不应使用过期的资源。

Cache-Control: must-revalidate

下面是一个缓存验证图

微信图片_20220412195644.jpg

什么是新鲜的数据

一旦资源存储在缓存中,理论上就可以永远被缓存使用。但是不管是浏览器缓存还是代理缓存,其存储空间是有限的,所以缓存会定期进行清除,这个过程叫做 缓存回收(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-ageexpires 都不存在,就去寻找 Last-Modified 标头,如果存在此标头,则高速缓存的有效性等于 Date 标头的值减去 Last-modified 标头的值除以10。

缓存验证

当到达缓存资源的有效期时,将对其进行验证或再次获取。仅当服务器提供了强验证器弱验证器时,才可以进行验证。

当用户按下重新加载按钮时,将触发重新验证。如果缓存的响应包含 Cache-control:must-revalidate标头,则在正常浏览下也会触发该事件。另一个因素是 高级 -> 缓存首选项 面板中的缓存验证首选项。有一个选项可在每次加载文档时强制进行验证。

Etag

我们上面提到了强验证器和弱验证器,实现验证器功能的标头正式 Etag 的作用,这意味着 HTTP 用户代理(例如浏览器)不知道该字符串表示什么,并且无法预测其值。如果 Etag 标头是资源响应的一部分,则客户端可以在未来请求的标头中发出 If-None-Match,以验证缓存的资源。

Last-Modified响应标头可以用作弱验证器,因为它只有1秒可以分辨的时间。如果响应中存在 Last-Modified标头,则客户端可以发出 If-Modified-Since请求标头来验证缓存资源。(关于 Etag 更多我们会在条件请求介绍)

避免碰撞

通过使用 Etag 和 If-Match 标头,你可以检测避免碰撞。

例如,在编辑 MDN 时,将对当前 Wiki 内容进行哈希处理并将其放入响应中的 Etag 中

Etag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

当将更改保存到 Wiki 页面(发布数据)时,POST 请求将包含 If-Match 标头,其中包含 Etag 值以检查有效性。

If-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

如果哈希值不匹配,则表示文档已在中间进行了编辑,并返回 412 Precondition Failed 错误。

缓存未占用资源

Etag 标头的另一个典型用法是缓存未更改的资源,如果用户再次访问给定的 URL(已设置Etag),并且该 URL过时,则客户端将在 If-None-Match 标头字段中发送其 Etag 的值

If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

服务器将客户端的 Etag(通过 If-None-Match 发送)与 Etag 进行比较,以获取其当前资源版本,如果两个值都匹配(即资源未更改),则服务器会发回 304 Not Modified状态,没有主体,它告诉客户端响应的缓存仍然可以使用。

HTTP CROS 跨域

CROS 的全称是 Cross-Origin Resource Sharing(CROS),中文译为 跨域资源共享,它是一种机制。是一种什么机制呢?它是一种让运行在一个域(origin)上的 Web 应用被准许访问来自不同源服务器上指定资源的机制。在搞懂这个机制前,你需要线了解什么是 域(origin)

Origin

Web 概念中域(Origin) 的内容由scheme(protocol) - 协议host(domain) - 主机和用于访问它的 URL port - 端口定义。仅仅当 scheme 、host、port 都匹配时,两个对象才有相同的来源。这种协议相同,域名相同,端口相同的安全策略也被称为 同源策略(Same Origin Policy)。某些操作仅限于具有相同来源的内容,可以使用 CORS 取消此限制。

跨域的特点

  • 下面是跨域问题的例子,看看你是否清楚什么是跨域了
(1) 
(2)

上面这两个 URL 是否具有跨域问题呢?

上面两个 URL 是不具有跨域问题的,因为这两个 URL 具有相同的协议(scheme)主机(host)

  • 那么下面这两个是否具有跨域问题呢?

这两个 URL 也不具有跨域问题,为什么不具有,端口不一样啊。其实它们两个端口是一样的。

或许你会认为这两个 URL 是不一样的,放心,关于一样不一样的论据我给你抛出来了

协议和域名部分是不区分大小写的,但是路径部分则根据服务器平台而定。Windows 和 Mac OS X 系统是不区分大小写的,而采用UNIX和Linux系的服务器系统是区分大小写的,

也就是说上面的 Example.comexample.com 其实是一个网址,并且由于两个地址具有相同的 scheme 和 host ,默认情况下服务器通过端口80传递 HTTP 内容,所以上面这两个地址也是相同的。

  • 下面这两个 URL 地址是否具有跨域问题?

这两个 URL 的 scheme 不同,所以这两个 URL 具有跨域问题

  • 再看下面这三个 URL 是否具有跨域问题

这三个 URL 也是具有跨域问题的,因为它们隶属于不通服务器的主机 host。

  • 下面这两个 URL 是否具有跨域问题

这两个 URL 也是具有跨域问题,因为这两个 URL 的默认端口不一样。

            </div>
目录
相关文章
|
自然语言处理 Java API
阿里云自然语言处理--文本相似度(电商)Java SDK 调用示例
自然语言处理(Natural Language Processing,简称NLP),是为各类企业及开发者提供的用于文本分析及挖掘的核心工具,旨在帮助用户高效的处理文本,已经广泛应用在电商、文娱、司法、公安、金融、医疗、电力等行业客户的多项业务中,取得了良好的效果。文本相似度可以提供不同文本之间相似度的计算,并输出一个介于0到1之间的分数,分数越大则文本之间的相似度越高。可广泛应用于信息检索,新闻推荐、智能客服等场景。使用该服务建议分数不要用于直接判断,可以作为特征,并按照范围进行分桶。本文将使用Java Common SDK 演示文本相似度(电商)服务的快速调用以供参考。
954 0
阿里云自然语言处理--文本相似度(电商)Java SDK 调用示例
|
Kubernetes Java Serverless
进击的 Serverless:Java 应用如何从容地面对突增流量
进击的 Serverless:Java 应用如何从容地面对突增流量
104371 88
|
人工智能 自然语言处理 搜索推荐
6个好用的AI写作工具合集,各种AI写作软件类型超全整理!
AI生成营销文案、生成文章标题、改写润色内容、写作素材搜集...好用的AI写作工具有哪些?
6个好用的AI写作工具合集,各种AI写作软件类型超全整理!
|
Android开发 开发者
HarmonyOS和OpenHarmony区别联系
【7月更文挑战第26天】
793 17
|
机器学习/深度学习 人工智能 算法
Copilot面临的挑战与问题
【2月更文挑战第16天】Copilot面临的挑战与问题
459 3
Copilot面临的挑战与问题
|
iOS开发 MacOS Windows
电脑怎么截图?截屏电脑快捷键ctrl加什么?
截图是我们日常使用电脑过程中非常常见的操作之一。无论是想保存有用的信息、分享有趣的内容,还是记录某个错误信息,截图都是一个简单而有效的方式。但是,不同的操作系统和需求会决定使用不同的方法来截图。接下来,我们将详细介绍几种在Windows和Mac电脑上常见的截图方法,帮助您快速掌握这一技能。
电脑怎么截图?截屏电脑快捷键ctrl加什么?
|
监控 数据可视化 搜索推荐
淘宝 API 接口的实际应用案例
淘宝API接口在电商领域扮演着重要角色,支持多种应用场景。一是助力电商数据分析公司获取商品详情,分析市场趋势、竞品及提出产品改进建议。二是支持商品比价网站收集价格信息,帮助消费者高效比价。三是赋能营销工具开发商实现自动化营销,提升客户转化率。四是协助跨境电商平台引进热门商品并进行本地化处理。最后,支持数据可视化工具展示销售趋势,辅助商家决策。
|
存储 数据库 文件存储
掌握Django文件处理:一步步构建上传功能
掌握Django文件处理:一步步构建上传功能
196 3
|
存储 弹性计算 固态存储
阿里云服务器配置怎么选择合适?收藏级教程大家参考下
阿里云服务器配置选择涉及CPU、内存、带宽和磁盘。个人开发者或中小企业推荐使用轻量应用服务器或ECS经济型实例,如2核2G3M配置,适合低流量网站。企业用户应选择企业级独享型ECS,如通用算力型u1、计算型c7或通用型g7,至少2核4G配置,公网带宽建议5M,系统盘可选SSD或ESSD云盘。具体配置需根据实际应用需求来定。
787 0