跨域资源共享 是一种允许网页向另一个域发出XMLHttpRequests的机制。
在过去的几天里,我一直在摆弄CORS,我认为我对所有工作原理都非常了解。
因此,我的问题不是关于CORS /预检如何工作,而是关于 将预检作为新的请求类型的原因 。我看不到任何原因,为什么服务器A需要向服务器B发送预检(PR)只是为了确定是否接受实际请求(RR)-B肯定有可能在没有请求的情况下接受/拒绝RR任何先前的PR。
经过大量搜索后,我在www.w3.org(7.1.5)上找到了以下信息:
为了保护资源免受在该规范存在之前可能源自某些用户代理的跨域请求,将进行预检请求以确保资源了解此规范。
我发现这是有史以来最难理解的句子。我的解释(最好将其称为“最佳猜测”)是关于保护服务器B免受来自服务器C的不知道该规范的请求的影响。
有人可以解释一个情况/显示PR + RR比单独使用RR更好地解决问题吗?
我花了一些时间对飞行前请求的目的感到困惑,但我想我现在已经明白了。
关键见解是,起飞前的要求不是 安全的 事情。相反,它们是 不变的规则 。
预检请求与安全无关,并且与具有CORS意识的当前开发的应用程序无关。相反,预检机制 会使 在不了解CORS的 情况下 开发的服务器受益,并且它充当客户端和服务器之间是否都知道CORS的健全性检查。CORS的开发人员认为那里有足够的服务器依赖于它们永远不会收到的假设,例如,跨域DELETE请求他们发明了预检机制以允许双方选择加入。他们认为,仅允许跨域调用的替代方案将破坏太多现有应用程序。
这里有三种情况:
不再开发的旧服务器,并且是在CORS之前开发的。这些服务器可能会假设它们永远不会收到例如跨域DELETE请求。 这种情况是预检机制的主要受益者。 是的,这些服务可能已经被恶意的或不合格的用户代理滥用了(并且CORS并没有做任何改变),但是在CORS的世界中,预检机制提供了额外的“健全性检查”,因此客户端和服务器不必中断,因为网络的基本规则已更改。
仍在开发中的服务器,但是其中包含许多旧代码,并且对于这些服务器不可行/不希望审核所有旧代码以确保其在跨域环境中正常运行。这种情况允许服务器逐步加入CORS,例如说“现在我将允许这个特定的标头”,“现在我将允许这个特定的HTTP动词”,“现在我将允许cookie / auth信息成为已发送”等。 这种情况将从预检机制中受益。
编写具有CORS意识的新服务器。根据标准的安全惯例,服务器必须面对 任何 传入请求来保护其资源-服务器无法信任客户端不进行恶意操作。 此方案无法从预检机制中受益 :预检机制不会为已正确保护其资源的服务器带来额外的安全性。