type="module"不控制沙箱权限,仅切换es模块执行模型;其加载与执行受限于协议安全性:https下正常支持import、cors跨域及modulepreload,http下因混合内容策略受限,file://协议则完全禁止。

type="module" 本身不直接控制沙箱权限,它只切换脚本的执行模型(ES模块规范),而模块能否加载、解析、执行,取决于协议安全性和浏览器对资源加载的策略——关键差异不在“模块”本身,而在协议引发的跨域与加载限制。
HTTPS 下模块脚本可正常加载和执行
现代浏览器允许在 HTTPS 页面中自由使用 type="module":
- 支持
import静态导入本地文件(如./utils.js)、绝对路径(/assets/main.js)或 CDN 地址(https://cdn.example.com/lib.mjs) - 跨域模块需服务端返回合法 CORS 头(如
Access-Control-Allow-Origin: *),并配合crossorigin属性使用 -
modulepreload可预加载 HTTPS 模块,且能递归触发依赖发现(需手动配置依赖项) - 所有模块行为按标准执行:作用域隔离、默认 defer、顶层 await 支持、静态路径解析等
HTTP 页面中模块脚本受限但未必完全失效
HTTP 协议本身不禁止 type="module",但存在两类硬性拦截:
- 本地 file:// 协议下彻底拒绝:Chrome/Firefox/Safari 均不发起任何请求,控制台仅显示空错误或泛化 CORS 错误(实际未走网络)
-
HTTP 站点中部分功能被降级或阻断:
- 从 HTTPS CDN 导入模块(如
import { debounce } from 'https://cdn.skypack.dev/lodash-es')会因混合内容(mixed content)被浏览器主动拦截 - 使用
importmap加载裸 specifier(如'lodash')时,若映射目标是 HTTPS 地址,在 HTTP 页面中仍可能被拒绝(取决于 UA 策略) -
modulepreload对跨域模块要求更严,HTTP 页面中若未配crossorigin或服务端缺 CORS 头,预加载静默失败
- 从 HTTPS CDN 导入模块(如
沙箱权限不是由 type="module" 控制,而是由协议+上下文共同决定
所谓“沙箱”,实际体现为三类限制:
- 加载沙箱:file:// 和 HTTP 页面对模块 URL 的解析/请求权限不同(前者全禁,后者部分禁)
- 执行沙箱:模块本身始终有独立作用域、严格模式、顶层 this === undefined —— 这与协议无关,HTTPS 或 HTTP 下行为一致
-
跨域沙箱:是否允许读取响应体、是否暴露
Response元数据、是否支持import()动态加载外部地址 —— 这些取决于目标资源是否满足当前页面的混合内容策略和 CORS 要求
开发建议:避免 HTTP + module 的组合
即使 HTTP 页面能加载同域模块,也不推荐用于真实开发:
- 本地调试务必用本地服务器(如
npx serve、python3 -m http.server或 Vite 内置 server),而非双击打开 HTML - 生产环境必须强制 HTTPS,否则现代浏览器会标记为“不安全”,且第三方模块(尤其是 CDN 版 ESM)大概率无法加载
- 若需兼容旧环境,可用
<script nomodule></script>提供降级脚本,但不要指望 HTTP 下的模块能稳定运行











