我一直在研究一个经典的SPA,其中前端应用程序存在于app.example.com
上,而API存在于api.example.com
上,因此需要使用CORS请求。已将服务器设置为返回 CORS 标头,工作正常。
每当 AJAX 请求不简单时,浏览器都会向服务器发出额外的OPTIONS
请求,以确定它是否可以使用有效负载进行调用。在 MDN 上查找简单请求
问题是:执行 OPTIONS 请求的实际好处是什么,尤其是在安全性方面?
我的应用程序的某些用户具有明显的地理延迟,并且由于预检缓存不会持续很长时间,因此预检请求会导致延迟成倍增加。
我希望使POST
请求变得简单,但只是嵌入application/json
Content-Type
就可以否定这一点。一种可能的解决方案是通过在 url 中使用text/plain
或编码来"破解"它。因此,我希望在离开时充分了解 CORS 预检请求对 Web 安全的作用。谢谢。
如您链接到的文章中所述:
这些是 Web 内容可以的相同类型的跨站点请求 已发出,并且没有响应数据发布给请求者 除非服务器发送适当的标头。因此,网站 防止跨站点请求伪造没有什么新东西需要担心 HTTP 存取控制。
基本上,这样做是为了确保 CORS 不会为跨域请求引入任何额外的方法,否则如果没有 CORS 就会被阻止。
例如,如果没有 CORS,以下表单内容类型只能通过实际的 <form>
标记跨域完成,而不能通过 AJAX 请求完成:
- application/x-www-form-urlencoded
- 多部分/表单数据 文本
- /纯文本
因此,任何接收具有上述内容类型之一的请求的服务器都知道它有可能来自另一个域,并且知道采取措施防止跨站点请求伪造等攻击。其他内容类型(如 application/json
(以前只能从同一域创建,因此不需要额外的保护。
类似地,具有额外标头的请求(例如 X-Requested-With
(以前也会受到类似的保护,因为它们只能来自同一个域(<form>
标签不能添加额外的标头,这是以前进行跨域 POST 的唯一方法(。GET 和 POST 也是表单支持的唯一方法。此处也列出了 HEAD,因为它的执行方式与 GET 相同,但没有检索消息正文。
因此,简而言之,它将首先阻止发出"非简单"请求,而无需调用 OPTIONS 来确保客户端和服务器都在使用 CORS 语言。请记住,同源策略仅阻止来自不同源的读取,因此仍然需要预检机制来防止写入发生 - 即在 CSRF 场景中执行不安全的方法。
您可以使用 Access-Control-Max-Age
标头提高性能。详情请见此处。