找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

862

积分

0

好友

108

主题
发表于 4 天前 | 查看: 10| 回复: 0

在浏览器中,内容可以加载各种资源,如 JavaScript 文件、图片、音频、视频等。但如果没有安全策略的限制,将会面临多种安全威胁,例如跨站脚本攻击(XSS)、SQL 注入、跨站点请求伪造(CSRF)等。为了保障用户隐私和数据安全,浏览器实施了最核心的安全策略:同源策略

什么是同源策略?

同源策略是一个重要的安全策略,用于限制一个源的文档或脚本如何与另一个源的资源进行交互。如果两个 URL 的协议、主机和端口都相同,则称这两个 URL 同源。

同源策略主要表现在以下三个方面,构成了现代Web安全的基石

  1. DOM 访问限制:阻止网页脚本(如 JavaScript)访问其他源的 DOM,防止恶意网站窃取敏感信息。
  2. Web 数据限制:限制了从其他源加载 Web 数据(例如通过 XMLHttpRequestFetch API)。默认情况下,这些请求只能发送到与当前网页同源的地址,以防止 CSRF 等攻击。
  3. 网络通信限制:浏览器会阻止从一个源发出的请求获取来自其他源的响应,确保只有受信任的源能与服务器通信。

出于上述安全原因,浏览器默认限制从脚本内发起的跨源 HTTP 请求。这意味着,使用 XMLHttpRequestFetch API 通常只能访问同域资源,除非目标服务器明确允许跨域访问。

CORS:跨源资源共享机制

“浏览器限制”更准确的理解是:跨站请求可以被正常发起,但返回结果可能被浏览器拦截。为了在安全的前提下实现合法的跨域数据交换,W3C 推出了 跨源资源共享(CORS) 机制。

CORS 允许服务器通过设置特定的 HTTP 响应头,来声明哪些外部源有权访问其资源。当浏览器发起跨域请求时,会根据服务器返回的这些 CORS 头部决定是否允许前端 JavaScript 访问响应数据。

根据请求的复杂性,CORS 将请求分为两类:简单请求和非简单请求(需预检请求)。

简单请求

满足以下所有条件的请求被视为简单请求,不会触发预检:

  1. 方法限制:仅使用 GET、HEAD、POST 方法之一。
  2. 标头限制:除用户代理自动设置的标头外,仅允许使用以下标头:AcceptAccept-LanguageContent-LanguageContent-Type(值仅限于 application/x-www-form-urlencodedmultipart/form-datatext/plain)。
  3. 请求中没有使用 ReadableStream 对象。

对于简单请求,浏览器会直接发出请求,并在请求头中自动添加 Origin 字段,服务器通过响应头 Access-Control-Allow-Origin 来决定是否允许跨域。

预检请求

不满足简单请求条件的请求(例如使用了 PUTDELETE 方法,或 Content-Typeapplication/json,或设置了自定义头),浏览器会首先自动发起一个 OPTIONS 方法的预检请求到服务器,以获知服务器是否允许该实际请求。

例如,一个携带自定义头 x-secsdk-csrf-token 的 POST 请求,浏览器会先发送 OPTIONS 请求进行“询问”。

预检请求的关键头部:

  • Access-Control-Request-Method:告知服务器,实际请求将使用的 HTTP 方法(如 POST)。
  • Access-Control-Request-Headers:告知服务器,实际请求将携带的自定义头部字段列表。

服务器响应的关键头部:

  • Access-Control-Allow-Origin:允许跨域请求的源,可以是具体域名或 *(通配符,但有使用限制)。
  • Access-Control-Allow-Methods:允许使用的 HTTP 方法列表。
  • Access-Control-Allow-Headers:允许携带的请求头列表。
  • Access-Control-Max-Age:指定本次预检响应的有效时间(秒),在此期间内不再发送预检请求。

一旦预检请求通过,浏览器才会发出实际的 POST 请求。这就是为什么某些 POST 请求看起来会发送两次(一次 OPTIONS 预检,一次实际的 POST)的根本原因。

附带凭证的请求与安全限制

当请求需要携带 Cookie 等身份凭证时(通过在 XMLHttpRequestFetch 中设置 withCredentials = true),安全性要求更高:

  1. 服务器不能将 Access-Control-Allow-Origin 设置为通配符 *,必须指定明确的域名(如 Access-Control-Allow-Origin: https://example.com)。
  2. 同样,Access-Control-Allow-HeadersAccess-Control-Allow-Methods 也应尽量避免使用 *,而提供明确的列表。
  3. 服务器响应可能需要包含 Access-Control-Allow-Credentials: true 头部。

完整的CORS请求流程

下图清晰地展示了简单请求与需预检请求的完整流程差异:
CORS请求完整流程图

总结

预检请求是 CORS 机制中用于保障安全的重要环节。它通过一次“前置询问”(OPTIONS 请求),让服务器有机会对非简单的跨域HTTP请求进行审查和授权,声明允许的方法、头部和来源。这有效防止了恶意网站滥用跨域请求,保护了用户数据和服务器资源。理解预检请求,对于前端开发者处理网络请求与API交互至关重要。




上一篇:SpaceX上市计划确认:为构建太空AI算力数据中心注入万亿资本
下一篇:麒麟9030系列芯片架构解析:极客湾为何暂缓测评背后的技术推演
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 17:47 , Processed in 0.197058 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表