Node.js中发送HTML响应及处理请求响应的正确方式
原写法的问题
- 服务创建逻辑位置错误:
http.createServer仅需在服务启动阶段执行1次,放在fs.readFile回调中会导致服务启动依赖文件读取结果,后续要返回多文件时必然出现重复创建服务的冗余逻辑。 - 无路由匹配逻辑:当前写法无论请求路径、请求方法是什么,都会固定返回同一个
index.html内容,无法满足多页面响应需求。 - 异常处理缺失:没有处理文件不存在、非法请求路径等场景的错误返回,也没有设置正确的字符编码,很容易出现中文乱码问题。
Node.js 发送HTML响应的标准原生实现
核心原则:服务全局只创建一次,请求触发时再根据请求信息匹配、读取对应文件返回,不要将服务实例初始化逻辑嵌入IO操作回调中。
可直接运行的参考实现:
const http = require('http'); const fs = require('fs'); const path = require('path'); // 静态HTML文件存放的根目录 const HTML_ROOT = path.resolve(__dirname, '../Html'); // 服务仅初始化一次 const server = http.createServer((req, res) => { // 只处理GET类型的页面请求 if (req.method !== 'GET') { res.statusCode = 405; res.setHeader('Content-Type', 'text/plain; charset=utf-8'); return res.end('请求方法不允许'); } // 路由匹配:访问根路径默认返回index.html,其他路径按url匹配对应文件 const reqPath = req.url === '/' ? '/index.html' : req.url; // 拼接得到目标文件的绝对路径 const targetPath = path.join(HTML_ROOT, reqPath); // 路径安全校验:防止目录遍历攻击,禁止访问HTML根目录之外的文件 if (!targetPath.startsWith(HTML_ROOT)) { res.statusCode = 403; res.setHeader('Content-Type', 'text/html; charset=utf-8'); return res.end('<h1>403 禁止访问</h1>'); } // 请求到来时再读取目标文件返回 fs.readFile(targetPath, (err, fileData) => { if (err) { // 文件不存在返回404 if (err.code === 'ENOENT') { res.statusCode = 404; res.setHeader('Content-Type', 'text/html; charset=utf-8'); return res.end('<h1>404 页面不存在</h1>'); } // 其他读取错误返回500 res.statusCode = 500; res.setHeader('Content-Type', 'text/html; charset=utf-8'); return res.end('<h1>500 服务器内部错误</h1>'); } // 正常返回HTML内容,明确设置utf-8编码避免乱码 res.statusCode = 200; res.setHeader('Content-Type', 'text/html; charset=utf-8'); res.end(fileData); }); console.log('收到请求:', req.method, req.url); }); // 启动监听,不需要等待文件读取操作 server.listen(3000, 'localhost', () => { console.log('服务已启动,监听 localhost:3000'); });
实践建议
- 原生手写HTTP服务仅适合学习底层原理,生产环境直接使用成熟框架即可,不需要重复造轮子:比如Express可以直接用
express.static中间件托管静态HTML文件,Koa可以用koa-static中间件,内置了路径安全、缓存控制、MIME类型自动识别等能力,稳定性更高。 - 不要在请求处理流程中使用
fs.existsSync、fs.readFileSync这类同步IO方法,会阻塞Node.js事件循环,导致服务并发能力大幅下降。 - 返回HTML响应时必须在
Content-Type头中声明charset=utf-8,否则页面中的中文内容会出现乱码。
内容的提问来源于stack exchange,提问作者Isa Özsoy
相关产品推荐
相关产品推荐

