加了 crossorigin="anonymous" 仍是“script error.”是因为服务端未返回匹配的 access-control-allow-origin 响应头,导致脚本加载失败或错误信息被屏蔽;该属性仅启用 cors 加载模式并允许获取详细错误信息,但需服务端配合。

为什么加了 crossorigin="anonymous" 还是 "Script error."
因为 crossorigin="anonymous" 只是让浏览器「愿意去看」跨域脚本的错误,但前提是服务端必须返回匹配的 Access-Control-Allow-Origin 响应头。没这个头,浏览器连资源都不给你,window.onerror 根本不会触发——你看到的不是“报错被屏蔽”,而是“压根没加载成功”。
- 服务端响应里没有
Access-Control-Allow-Origin→ 控制台报 CORS 错误,JS 不执行,onerror不触发 - 服务端返回了
Access-Control-Allow-Origin: *,但页面用了crossorigin="use-credentials"→ 请求被浏览器直接拦截(*和凭据互斥) - 服务端返回
Access-Control-Allow-Origin: https://a.com,但当前页面是https://a.com/(多了一个斜杠)→ 源不完全匹配,校验失败 - 本地双击 HTML 文件(
file://协议)→crossorigin被忽略,错误照旧被屏蔽
crossorigin="anonymous" 到底做了什么
它不是“打开跨域”,而是告诉浏览器:“请用 CORS 模式加载这个脚本,且不要带 Cookie 或 Authorization 头”。这带来两个实际变化:
- 请求头里会带上
Origin字段(如Origin: https://your-site.com) - 加载成功后,如果脚本执行出错,
window.onerror的error参数能拿到完整堆栈、lineno、colno,而不是空的"Script error." - 同时启用
integrity校验(没这个属性,integrity会被忽略)
注意:crossorigin="" 或 crossorigin(无值)等价于 anonymous,但语义模糊,建议显式写出。
Webpack/Vite 动态 import() 加载的 chunk 容易漏配
静态 <script></script> 标签好加 crossorigin="anonymous",但工程化项目里大量 JS 是通过 import() 动态加载的——这些 chunk 默认不走 CORS 流程,错误监控照样收不到堆栈。
- Webpack:必须在
webpack.config.js中设置output.crossOriginLoading: 'anonymous' - Vite:需在
vite.config.ts的build.rollupOptions.output中设crossOrigin: 'anonymous',或用插件注入 script 标签属性 - 没配的话,控制台只显示
"Script error.",排查时根本不知道错在哪一行
同域脚本加 crossorigin="anonymous" 有没有用
没用,还可能引入风险。
- 同域请求加了该属性,浏览器仍会发
Origin头,但服务端若没配Access-Control-Allow-Origin,某些中间件(比如 Nginx 默认配置)会丢掉Origin,导致预检失败或响应被拒 - 即使服务端返回了
Access-Control-Allow-Origin: *,也属于过度开放,存在潜在安全风险 -
window.onerror能捕获错误,但这不是crossorigin带来的收益,而是同域本就支持的行为
真正需要它的,只有明确跨域的资源,比如 CDN 上的 https://cdn.example.com/app.js。其他场景加了反而容易踩坑。











