在本地通过 script 标签以 type="module" 的方式引用 main.js 时,出现跨域问题(CORS 错误)的原因是:浏览器对 ES 模块的加载有严格的同源策略限制。
1. 为什么会报跨域错误?
当你在本地直接打开 index.html 文件(例如通过 file:// 协议),浏览器会以严格的安全模式运行。此时,使用 type="module" 加载的 JavaScript 文件会被视为跨域请求,因为:
file://协议不支持跨域请求:浏览器会将本地文件系统视为一个独立的源(origin),而加载模块时会被认为是跨域请求。- ES 模块的严格限制:浏览器要求模块必须通过 HTTP(S) 协议加载,且必须遵循同源策略或正确的 CORS 配置。
2. 如何解决这个问题?
方法 1:使用本地服务器
最简单的方法是使用一个本地开发服务器来运行你的项目,而不是直接通过 file:// 协议打开文件。常见的本地服务器工具有:
- VS Code 的 Live Server 插件:
- 安装 Live Server 插件。
- 右键点击
index.html,选择Open with Live Server。
方法 2. 使用 http-server
-
使用
http-server:- 安装
http-server:npm install -g http-server - 在项目根目录下运行:
http-server - 打开浏览器访问
http://localhost:8080。
- 安装
-
使用
Python内置服务器:- 在项目根目录下运行:
python -m http.server - 打开浏览器访问
http://localhost:8000。
- 在项目根目录下运行:
方法 3. 使用 Python 内置服务器
如果你已经安装了 Python,可以使用它的内置 HTTP 服务器。
步骤:
- 打开终端,进入项目根目录。
- 运行以下命令:
- 对于 Python 3:
python -m http.server - 对于 Python 2:
python -m SimpleHTTPServer
- 对于 Python 3:
- 默认地址是
http://127.0.0.1:8000。
优点:
- 无需额外安装:Python 自带。
- 简单易用。
方法 4. 使用 Webpack Dev Server
如果你正在使用 Webpack,可以使用 webpack-dev-server。
步骤:
- 安装
webpack-dev-server:npm install --save-dev webpack-dev-server - 在
webpack.config.js中配置:module.exports = { // 其他配置 devServer: { static: './dist', // 项目根目录 port: 3000, // 端口号 }, }; - 启动服务器:
npx webpack serve - 默认地址是
http://localhost:3000。
优点:
- 适合复杂项目:支持热更新、模块打包等功能。
方法 5. 使用 Node.js 自定义服务器
如果你熟悉 Node.js,可以自己写一个简单的 HTTP 服务器。
步骤:
- 创建一个
server.js文件:const http = require('http'); const fs = require('fs'); const path = require('path'); const server = http.createServer((req, res) => { const filePath = path.join(__dirname, req.url === '/' ? 'index.html' : req.url); fs.readFile(filePath, (err, data) => { if (err) { res.writeHead(404); res.end('File not found'); } else { res.writeHead(200); res.end(data); } }); }); server.listen(3000, () => { console.log('Server is running on http://localhost:3000'); }); - 启动服务器:
node server.js - 打开浏览器访问
http://localhost:3000。
优点:
- 完全自定义:可以根据需求扩展功能。
3. 为什么需要本地服务器?
- 模拟真实环境:本地服务器会通过
http://或https://协议提供服务,更接近生产环境。 - 支持模块化加载:浏览器对模块化脚本的加载要求严格,本地服务器可以避免跨域问题。
- 支持其他功能:本地服务器还可以支持热更新、路由配置等功能。