You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何fetch请求同URL报CORS错误,动态插入script标签却正常?

跨域请求表现差异的核心原因

问题中提到的动态注入script标签的实现代码如下:

((global, url) => {
    let s = document.createElement('script')
    s.src = url 
    global.document.body.appendChild(s)
})(window, 'https://example.com')

同样请求https://example.com,动态script标签可以正常加载执行脚本,fetch调用却触发CORS错误,本质是浏览器对两类不同用途的资源请求,施加了完全不同的跨域安全策略,和URL本身没有关系。

动态注入script标签的请求逻辑

动态插入script标签加载资源,属于浏览器从Web诞生初期就支持的跨源资源嵌入能力:

  • 这类能力的设计初衷是允许页面嵌入跨域的脚本、图片、样式等可直接被浏览器渲染/执行的资源,前端JS没有权限读取这类请求的响应原始文本
  • 代码执行后浏览器会正常向目标地址发起GET请求,不会提前做跨域拦截
  • 服务端返回响应后,浏览器会直接把响应内容当作JavaScript脚本在当前页面上下文执行,整个过程不需要服务端返回Access-Control-Allow-Origin这类CORS相关响应头
  • 早年广泛使用的JSONP跨域方案,就是基于这个特性实现的

fetch发起请求的校验逻辑

fetch属于跨源数据读取类API,和资源嵌入的逻辑完全不同:

  • 这类API的设计目标就是允许前端JS直接获取、自由操作响应的原始内容,因此浏览器会对其严格执行CORS校验规则,防止恶意站点私自读取用户在其他站点的隐私数据
  • 哪怕请求URL、请求方法和script标签加载的完全一致,浏览器也会在收到响应后校验服务端是否返回了合法的CORS响应头
  • 如果服务端没有配置匹配当前源的Access-Control-Allow-Origin等合法CORS头,浏览器会直接拦截响应内容,禁止JS读取任何响应数据,同时抛出CORS跨域错误

常见认知误区:跨域限制不代表请求被浏览器拦截无法发送。绝大多数场景下跨域请求都会正常发送到服务端,服务端也会正常处理并返回响应,区别只是浏览器会不会把响应内容开放给前端JS代码读取。script标签场景下浏览器自行消费响应内容(执行脚本),不需要开放读取权限,因此不需要CORS许可;fetch场景下JS需要直接读取响应内容,就必须通过CORS校验。

内容的提问来源于stack exchange,提问作者Ariel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:30:53