
直接双击打开 HTML 文件时,type="module 脚本一定会因 CORS 失败——这不是配置问题,是浏览器强制行为。必须用 http:// 或 https:// 协议访问,否则连请求都不会发。
为什么 file:// 下 type="module" 会静默失败
Chrome、Edge、Firefox 在 file:// 协议下把页面源视为 origin 'null',而模块加载的 Sec-Fetch-Mode 默认是 cors,CORS 规范明确禁止从 null 源发起跨源请求。结果不是报错“找不到文件”,而是控制台只显示:
Access to script at 'file:///xxx.js' from origin 'null' has been blocked by CORS policy.
注意:这个错误常被误判为路径写错,其实脚本压根没被浏览器发出请求。
同源模块的路径必须带扩展名和相对/绝对前缀
即使服务已跑在 http://localhost:5173 上,模块内 import 仍受严格路径校验:
-
import { foo } from './utils.js'✅ 正确:有./前缀 +.js扩展名 -
import { foo } from './utils'❌ 报Failed to load module script:浏览器不补扩展名 -
import { foo } from 'utils.js'❌ 报SyntaxError: Unexpected token 'export':裸路径不被允许,无法判断是相对还是绝对 -
import { foo } from '/js/utils.js'✅ 可行:根相对路径,前提是服务器能响应该 URL
跨域模块(如 CDN)必须加 crossorigin 属性
引入第三方模块时,仅写 <script type="module" src="https://cdn.jsdelivr.net/npm/axios@1.6.7/dist/axios.min.js"></script> 不够,缺少 crossorigin 会导致静默失败(控制台可能无提示,或只报 CORS):
<script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/axios@1.6.7/dist/axios.min.js"></script>
原因:crossorigin 决定了 fetch 的凭据模式;CDN 返回的 JS 必须带 Access-Control-Allow-Origin: *(或具体域名),且浏览器需以 cors 模式发起请求,二者缺一不可。
modulepreload 也受 CORS 约束,且不递归预加载依赖
想提前加载模块?不能用 <link rel="preload">,得用 modulepreload:
<link rel="modulepreload" href="/app.js">
但要注意两点:
- 该
href必须与后续<script type="module" src="/app.js"></script>的src完全一致(含查询参数,如?v=1) - 它只下载
/app.js,不会下载其内部import './utils.js'的依赖——那些得单独再写一条modulepreload
所有 modulepreload 请求同样走 CORS 流程,跨域资源也必须配 crossorigin 和服务端 CORS 头。
最容易被忽略的一点:模块加载的“跨域”判定发生在解析阶段,不是执行时。哪怕你只是写了 import 语句但没实际调用,只要路径非法或 CORS 不通过,整个模块就会中止加载,后续逻辑不会执行。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











