浏览器的 JS 模块化支持观察记录
1、具体实现
-
文件结构
module_test
├── test.html
├── test.js
└── math.js
- index.html
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>test</title>
</head>
<body></body>
<script type="module" src="test.js"></script>
<!-- <script type="module">
import { add } from "./math.js";
const result = add(2, 3);
console.log(result);
</script> -->
</html>
- test.js
js
import { add } from "./math.js";
const result = add(2, 3);
console.log(result);
- math.js
js
export function add(a, b) {
return a + b;
}
2、测试
-
直接在浏览器中打开
test.html文件,输出如下错误信息Access to script at 'file:///D:/WebCode/module_test/test.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: chrome-extension, chrome-untrusted, data, edge, http, https, isolated-app.
Failed to load resource: net::ERR_FAILED
Unsafe attempt to load URL file:///D:/WebCode/module_test/test.html from frame with URL file:///D:/WebCode/module_test/test.html. 'file:' URLs are treated as unique security origins.
3、问题原因
- 这是 ES Modules 在
file://协议下的 CORS 限制,这是浏览器的安全策略
-
浏览器将
file://协议视为不安全的 null origin -
ES Modules 要求通过 HTTP/HTTPS 协议加载,不能使用
file://协议 -
从
file://页面加载另一个file://文件被视为跨域请求
4、处理策略
- 使用 VSCode 的 Live Server 插件,打开
test.html文件
5、补充学习
js
import { add } from "math.js";
const result = add(2, 3);
console.log(result);
-
test.js,写成上述内容,通过 Live Server 插件,打开
test.html文件,输出如下错误信息Uncaught TypeError: Failed to resolve module specifier "math.js". Relative references must start with either "/", "./", or "../".
-
浏览器必须明确知道模块的完整路径,裸模块名(不以
/、./、../开头)不会被浏览器自动解析 -
使用相对路径导入模块,
import { add } from "./math.js"