html本身不跨域,真正起作用的是浏览器同源策略;img、link、script等标签可加载跨域资源但不可读取内容,fetch/xhr因可读响应体而受cors严格限制。

HTML本身不“跨域”,所谓“HTML跨域”其实是误解;真正起作用的是浏览器对资源加载和脚本交互的限制规则——也就是同源策略。页面里写一个 <img src="https://cdn.example.com/logo.png?x-oss-process=image/resize,p_40"> 能正常加载,但用 fetch() 去请求同一张图的二进制内容却失败,这就是同源策略在起作用,不是HTML“允许跨域”,而是某些标签天生绕过读取限制。
哪些HTML标签能天然加载跨域资源
浏览器明确允许部分标签发起跨域请求并渲染结果,但不赋予JavaScript访问响应内容的权限。这是安全设计的折中:资源可用,但不可读。
-
<img>、<link rel="stylesheet">、<script src></script>、<video></video>、<audio></audio>都能加载非同源资源 -
<iframe></iframe>可以嵌入跨域页面,但父页 JS 无法读取其contentDocument或执行 DOM 操作(除非对方配合设置document.domain或启用postMessage) - 这些标签的请求不会触发 CORS 预检(OPTIONS),也不受
Access-Control-Allow-Origin响应头影响——它们根本不要求“被允许”,只是被浏览器放行加载
为什么 fetch() 和 XMLHttpRequest 会被拦截
因为这两个 API 的设计目标是“可编程地读取响应体”,一旦开放任意跨域读取能力,就等于把用户 Cookie、登录态、私有数据暴露给任意第三方站点。同源策略在这里是硬性拦截点,不是协商机制。
- 即使服务器返回了正确数据,只要响应头缺失
Access-Control-Allow-Origin,fetch()的.then()就不会执行,控制台报错Blocked by CORS policy -
withCredentials: true时,Access-Control-Allow-Origin不能为*,必须是精确域名,否则浏览器直接拒绝解析响应 - 非简单请求(如带
Authorization头、Content-Type: application/json)会先发一次OPTIONS预检,服务端没配好就卡在预检阶段,连真实请求都发不出去
document.domain 能解决什么、不能解决什么
它只适用于**同主域、不同子域**的场景,比如 a.example.com 和 b.example.com,且仅对 cookie、iframe DOM 通信有效,对 fetch 无效。
- 必须两端同时执行
document.domain = "example.com",否则不生效 - 一旦设置,就不能再设回子域(比如从
"example.com"改成"a.example.com"),会抛SecurityError - 现代浏览器(Chrome 88+、Firefox 79+)已废弃对
document.domain的支持用于跨域通信,仅保留兼容旧逻辑;新项目应避免依赖
真正容易被忽略的是:同源策略不是“阻止请求发出”,而是“阻止脚本读取响应”。很多调试者看到 Network 面板里请求状态码是 200,就以为跨域成功了,其实 JS 根本拿不到 body——这个边界模糊点,是绝大多数 CORS 问题排查的第一盲区。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











