Node.js Web服务器导入.js/.mjs文件失败的问题求助
问题解决:Node.js服务器托管ES模块及函数调用错误
一、修复MIME类型错误
当前server.js的核心问题是无论浏览器请求什么资源,都强制返回text/html的Content-Type,当请求test.mjs时,服务器依然返回HTML类型的响应头,违反了ES模块严格的MIME类型检查规则。需要修改服务器逻辑,根据请求文件的后缀返回正确的Content-Type:
修改后的server.js代码:
const http = require('http') const fs = require('fs') const path = require('path') const port = 3000 const server = http.createServer(function(req, res){ // 根据请求路径确定目标文件 let filePath = '.' + req.url; if (filePath === './') { filePath = './test_functions.html'; // 默认加载首页 } // 根据文件后缀设置对应Content-Type const extname = path.extname(filePath); let contentType = 'text/html'; switch (extname) { case '.js': case '.mjs': contentType = 'text/javascript'; // ES模块需正确的JS MIME类型 break; case '.css': contentType = 'text/css'; break; case '.json': contentType = 'application/json'; break; } // 读取并返回文件 fs.readFile(filePath, function(error, data){ if(error){ res.writeHead(404, {'Content-Type': 'text/html'}); res.write('Error: File not found'); } else{ res.writeHead(200, {'Content-Type': contentType}); res.write(data); } res.end(); }) }) server.listen(port, function(error){ if (error){ console.log('Something went wrong', error) } else { console.log('Server is listening on port ' + port) } })
修改说明:
- 新增
path模块解析文件后缀,为.mjs/.js文件设置正确的text/javascript类型 - 不再固定返回
test_functions.html,而是根据请求URL动态加载对应资源,确保test.mjs能被正确请求
二、修复showAlert未定义错误
ES模块的默认导出不会自动挂载到全局作用域,因此HTML内联的onclick="showAlert()"无法直接访问该函数,提供两种解决方式:
方式1:将函数挂载到全局对象
修改test.mjs,把导出的函数绑定到window对象:
export default function showAlert() { alert("welcome"); } window.showAlert = showAlert; // 挂载到全局作用域 console.log('hello')
方式2:使用DOM事件监听替代内联onclick
修改test_functions.html,去掉内联事件,在模块中直接绑定监听(更符合ES模块规范,避免全局污染):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script type="module"> import showAlert from './test.mjs'; document.querySelector('input[type="button"]').addEventListener('click', showAlert); </script> </head> <body> <p>Hey, click on the button below to invoke the function</p> <input type="button" value="Click Me"> </body> </html>
内容的提问来源于stack exchange,提问作者Jeroen
相关产品推荐
相关产品推荐

