AI摘要
做过网页开发的朋友应该都有体会,HTML 给了我们极大的灵活性 —— 我们既可以写 <p>hello world</p> 这种基础内容,也能通过 <img src="https://othersite.com/hello.png"> 这种方式引用外部资源。但这种 “自由” 背后,其实藏着不少安全和使用上的坑,我踩过好几次,今天就结合自己的实际经历,把这些跨域相关的知识点捋清楚。
在 HTML 网页开发中,页面不仅能通过<p>hello world</p>这类标签提供本地内容,还可通过<img src="https://othersite.com/hello.png">形式内嵌外链资源。HTML 对资源引用的高自由度,为开发带来便利的同时,也引发了资源滥用、跨域接口被非法调用等安全问题,而 CORP、CORS、COOP、COEP 等浏览器安全策略,正是解决这类问题的核心方案,本文将逐一解析其作用与配置方式。
一、CORP(Cross-Origin Resource Policy)跨域资源策略
CORP 的核心作用是管控资源的跨源访问权限,即决定某一资源是否允许被其他源的页面引用加载,解决资源被非法套壳引用的问题。
典型场景下,若一个图库站点存放大量高清资源,未做权限限制时,其他站点可通过简单 HTML 搭建页面,直接引用该站点的图片资源,无需承担存储和带宽成本,造成原站点资源被滥用。此时可为图片资源配置 CORP 响应头,限制仅自身域名 / 同站域名可拉取资源。
CORP 响应头的核心取值及含义如下,浏览器会根据配置拦截非授权源的资源引用请求:
表格
| 值 | 描述 |
|---|---|
| same-origin | 仅允许同源(example.com)的页面拉取对应资源 |
| same-site | 仅允许同站(*.example.com/example.com)的页面拉取资源 |
| cross-origin | 【默认值】允许所有源的页面拉取资源,无访问限制 |
配置CORP: same-site后,非本站域名通过<img>等标签引用资源时,浏览器会直接阻断加载,从根源避免资源滥用。
二、CORS(Cross-Origin Resource Sharing)跨域资源共享
CORS 的核心作用是管控接口的跨源调用权限,即决定某一接口是否允许被其他源的页面请求、能否携带自定义头 / 凭据、能否读取非基础响应头等,是解决跨域接口调用问题的核心策略,比 CORP 的管控维度更细致,主要适用于 API 接口场景。
典型跨域调用问题及解决
- 接口被非法调用:若接口配置
Access-Control-Allow-Origin: *,表示允许所有源调用接口并获取响应,易导致自用接口被第三方非法请求。将该值改为指定业务域名(如yoursite.com),即可限制仅该域名能调用接口,第三方请求会被浏览器拦截。 - 无法读取跨源响应头:跨源请求接口时,浏览器默认仅允许 JS 读取
Content-Type等少数基础响应头,若需读取Server、X-Request-Id等自定义 / 非基础头,需配置Access-Control-Expose-Headers,指定允许暴露的响应头名称。 - 自定义请求头被拦截:跨源请求时携带自定义头,浏览器会拦截请求,需配置
Access-Control-Allow-Headers,指定允许携带的请求头名称,否则请求无法正常发送。
CORS 核心响应头配置
CORS 通过多个专属响应头实现精细化管控,各头的默认规则、取值及作用如下,覆盖 “谁能调、能怎么调、能拿什么数据” 全维度:
1. Access-Control-Allow-Origin(控制允许的请求源)
- 默认规则:默认不允许任何跨源请求
核心取值:
值 描述 *允许任意源访问资源(⚠️ 不可与 Access-Control-Allow-Credentials: true同时使用)https://example.com仅允许指定源访问资源,精准管控访问范围 null允许 Origin: null的源访问(如本地file://页面、沙盒 iframe)
2. Access-Control-Allow-Methods(控制允许的请求方式)
- 默认规则:默认不允许任何跨源请求方式
核心取值:
值 描述 GET/POST/PUT/DELETE/PATCH允许单个指定的 HTTP 请求方式 OPTIONS允许预检请求(跨域复杂请求的前置必选请求) GET, POST, OPTIONS允许多个请求方式,不同方式用英文逗号分隔
3. Access-Control-Allow-Headers(控制允许携带的请求头)
- 默认规则:仅允许携带 CORS 白名单内的基础请求头(如
Accept、Content-Type) 核心取值:
值 描述 Content-Type/Authorization允许携带指定的标准请求头 X-Custom-Header允许携带指定的自定义请求头 *允许携带所有请求头(现代浏览器支持,仅适用于非凭据请求)
4. Access-Control-Allow-Credentials(控制是否允许携带凭据)
- 默认规则:默认不允许携带任何凭据
核心取值:
值 描述 true允许跨源请求携带凭据(Cookie、Authorization、TLS 客户端证书等) (不返回该头) 默认行为,禁止携带任何凭据
5. Access-Control-Expose-Headers(控制允许读取的响应头)
- 默认规则:仅允许 JS 读取 CORS 白名单内的基础响应头
核心取值:
值 描述 X-Request-Id/Server允许 JS 读取指定的非基础响应头 Content-Length允许 JS 读取资源内容长度响应头 X-A, X-B允许读取多个响应头,不同头用英文逗号分隔
6. Access-Control-Max-Age(控制预检请求结果的缓存时间)
- 默认规则:默认不缓存预检请求结果,每次复杂跨域请求均需发送预检请求
核心取值:
值 描述 0不缓存预检请求结果,每次均需校验 600预检结果缓存 10 分钟,减少重复请求 86400预检结果缓存 24 小时(浏览器可能存在自身上限,以浏览器实际表现为准)
三、COOP & COEP 跨域隔离策略
COOP(Cross-Origin-Opener-Policy)和 COEP(Cross-Origin-Embedder-Policy)均为配置在 HTML 文档上的响应头,而非资源 / 接口,二者协同实现页面的跨域隔离,降低侧信道攻击、页面劫持等安全风险,还能解锁部分高权限 Web API 的使用权限。
1. COOP(Cross-Origin-Opener-Policy)跨域打开者策略
COOP 的核心作用是管控不同页面之间的浏览器窗口上下文(browsing context)共享权限,主要影响通过window.open()打开的页面与原页面之间的关系,以及是否允许互相访问window.opener属性,通过页面隔离降低信息泄露和劫持风险。
启用 COOP 后,浏览器会根据配置将跨源页面强制隔离到不同进程,禁止共享执行环境,其核心取值及行为如下:
表格
| 值 | 是否默认 | 行为描述 |
|---|---|---|
unsafe-none | ✅ 是 | 不启用任何隔离,跨源页面可共享窗口上下文与window.opener |
same-origin | ❌ | 仅允许同源页面共享窗口上下文和进程,跨源页面的window.opener置为 null |
same-origin-allow-popups | ❌ | 自身页面与跨源页面隔离,但允许弹出跨源窗口(适用于 OAuth 授权、支付弹窗等场景) |
2. COEP(Cross-Origin-Embedder-Policy)跨域嵌入者策略
COEP 的核心作用是管控页面对跨源资源的加载和使用权限,启用后,页面所有嵌入的跨源资源必须通过 CORP 或 CORS 完成授权,否则浏览器会在资源请求成功后,阻止页面使用该资源(并非拦截资源请求)。
其核心取值及行为如下,核心是确保页面仅能使用受信任的跨源资源:
表格
| 值 | 是否默认 | 行为描述 |
|---|---|---|
unsafe-none | ✅ 是 | 不启用任何嵌入限制,页面可加载并使用任意跨源资源 |
require-corp | ❌ | 仅允许加载并使用通过 CORP 或 CORS 明确授权的跨源资源 |
3. COOP & COEP 关键生效规则
- 生效范围:仅当页面作为文档(document)被加载时,浏览器才会检查并生效 COOP/COEP 配置,包括:顶级页面导航(地址栏直接打开)、iframe 中加载的文档、
window.open()打开的弹出窗口;图片、音频、视频、脚本等非文档资源,其响应头中的 COOP/COEP 配置无效,浏览器不会做任何检查。 - 生效时机:COOP 在页面创建 / 连接窗口上下文时生效,COEP 在页面尝试使用嵌入的跨源资源时生效。
4. COOP + COEP 联合效果
当一个 HTML 页面同时配置了 COOP 和 COEP,且页面中所有嵌入的跨源资源均满足 CORP/CORS 授权要求时,浏览器会将该页面标记为跨源隔离(cross-origin isolated) 状态。
处于该状态的页面,可安全使用部分高权限 Web API,例如SharedArrayBuffer、高精度计时器(performance.now()无精度限制)等,这类 API 因安全风险,默认仅对跨源隔离的页面开放。
四、浏览器安全模型完整流程图

核心总结
- 策略定位区分:CORP 管资源的跨源访问权限(能不能用资源),CORS 管接口的跨源调用权限(能不能调接口、能怎么调),COOP/COEP 管页面的跨域隔离规则(能不能共享窗口、能不能用未授权跨源资源);
- 配置载体区分:CORP、CORS 配置在资源 / 接口的响应头中,COOP、COEP 配置在HTML 文档的响应头中;
- 实用配置要点:跨源读取非基础响应头需配置
Access-Control-Expose-Headers,携带自定义请求头需配置Access-Control-Allow-Headers,解锁高权限 API 需同时配置 COOP+COEP 并满足跨源资源授权要求; - 生效范围区分:COOP/COEP 仅对 HTML 文档生效,非文档资源(图片、脚本等)不生效,CORP/CORS 则对资源和接口均生效。