跨域隔离要同时设两个响应头,第三方图片和脚本为什么会突然加载不出来
设了之后第三方图片和脚本加载不出来是怎么回事?这个问题通常出现在开发者给站点加上跨域隔离策略之后。跨域隔离需要同时设置两个响应头——Cross-Origin-Embedder-Policy 管本站文档允许加载哪些跨源资源,Cross-Origin-Opener-Policy 管窗口之间的引用关系——两者配合才能将文档标记为隔离环境。一旦隔离策略生效,页面上没有携带跨域许可标记的第三方图片和脚本就会被浏览器阻止加载。
两个响应头各自管什么
Cross-Origin-Embedder-Policy(缩写 COEP)决定当前文档能否引用跨源资源。未设置时浏览器按 unsafe-none 处理,不对跨源资源施加任何限制。一旦设为 require-corp,跨源资源必须以某种方式显式声明允许被本站引用,否则请求会被拦截。
Cross-Origin-Opener-Policy(缩写 COOP)决定当前文档与新开窗口的引用关系。设为 same-origin 后,新开的跨源窗口不再持有对原文档的 window.opener 引用,原文档也无法反向访问对方。这条策略切断了窗口间的跨域通道。
COEP 指令取值对照
| 指令 | 行为 |
|---|---|
| unsafe-none | 默认值,不施加跨源资源限制 |
| require-corp | 跨源资源须携带 crossorigin 属性或 Cross-Origin-Resource-Policy 头才允许加载 |
| credentialless | 允许无凭证的跨源请求,但响应不得包含 Cookie |
require-corp 是最常用的隔离模式。在这条规则下,页面引用外部域名的图片或脚本时,该资源的响应必须包含 Cross-Origin-Resource-Policy 放行标记,引用标签也需加上 crossorigin 属性。缺少任一侧的标记,浏览器视该资源为未授权并阻止加载。
两个头为什么必须成对设置
规范要求跨域隔离状态同时满足两个条件:COEP 设为 require-corp 或 credentialless,且 COOP 设为 same-origin。缺少任何一条,文档不会被标记为隔离环境。SharedArrayBuffer 和精确计时器依赖隔离状态才能使用,这是开发者设置响应头的常见动机。如果只设了 COEP 而未设 COOP,隔离虽未完全达成,但资源限制已经提前触发——第三方资源突然加载失败往往源于此。
第三方资源加载失败的排查思路
先确认隔离策略的实际生效范围。打开开发者工具 Console,查看是否存在资源被 COEP 阻止的报错信息,报错会给出被拦截资源的域名与所需标记。接着检查被拦截的第三方资源自身是否发送了 Cross-Origin-Resource-Policy 头;若资源由外部服务商托管,需联系对方在响应中补上该头。再检查页面引用标签是否添加了 crossorigin=“anonymous”;即使资源已携带 CORP 放行标记,标签侧缺少属性同样会被拦截。对于无法改造的第三方组件,可将其放在独立 iframe 内,并在该 iframe 的文档上不设置 COEP,从而绕开本站的隔离策略。
常见问题
Q:只设了 COEP 没设 COOP,为什么第三方图片已经加载不了?
A:COEP 的资源限制独立于隔离状态生效。只要响应头包含 require-corp,跨源资源就需满足标记要求,无论 COOP 是否设置。隔离未完全达成不代表限制未触发。
Q:跨域许可标记应该加在哪一侧?
A:需要两侧同时满足。引用标签侧添加 crossorigin 属性,资源服务侧添加 Cross-Origin-Resource-Policy 头。任何一侧缺少都可能导致加载失败。
Q:credentialless 能否替代 require-corp?
A:credentialless 允许发送不含凭证的跨源请求,适合加载无法改造的第三方图片。但仍需 COOP 设为 same-origin 才能启用跨域隔离,且并非所有浏览器都完整支持该指令,部署前需确认目标浏览器兼容性。