您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 如何用Node.js的http模块创建一个简单的静态资源服务器
## 前言
在现代Web开发中,静态资源服务器是基础但至关重要的组件。虽然Express等框架能快速搭建服务,但理解底层原理同样重要。本文将手把手教你用Node.js原生`http`模块构建一个静态资源服务器,涵盖核心实现、性能优化和错误处理。
---
## 一、项目初始化
首先创建项目目录并初始化:
```bash
mkdir static-server && cd static-server
npm init -y
安装必要依赖(非必须,但方便开发):
npm install mime-types --save
创建server.js
文件,编写最简HTTP服务器:
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 3000;
const server = http.createServer((req, res) => {
// 请求处理逻辑将在这里实现
res.end('Hello from static server!');
});
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}`);
});
此时运行node server.js
访问localhost:3000
会看到欢迎消息。
const server = http.createServer((req, res) => {
// 获取请求路径并规范化
let filePath = path.join(
__dirname,
'public',
req.url === '/' ? 'index.html' : req.url
);
// 处理路径遍历攻击
filePath = path.normalize(filePath);
if (!filePath.startsWith(path.join(__dirname, 'public'))) {
res.statusCode = 403;
return res.end('Forbidden');
}
});
fs.readFile(filePath, (err, content) => {
if (err) {
if (err.code === 'ENOENT') {
// 文件不存在
res.statusCode = 404;
res.end('File not found');
} else {
// 其他服务器错误
res.statusCode = 500;
res.end('Server error');
}
} else {
// 成功读取文件
res.end(content);
}
});
使用mime-types
库自动识别MIME类型:
const mime = require('mime-types');
// 在成功读取文件后添加:
const contentType = mime.lookup(filePath) || 'application/octet-stream';
res.setHeader('Content-Type', contentType);
添加浏览器缓存支持:
res.setHeader('Cache-Control', 'public, max-age=3600'); // 缓存1小时
避免内存溢出,改用流式传输:
const stream = fs.createReadStream(filePath);
stream.on('error', (err) => {
// 错误处理
});
stream.pipe(res);
添加gzip压缩(需zlib
模块):
const zlib = require('zlib');
// 检查客户端是否支持gzip
const acceptEncoding = req.headers['accept-encoding'] || '';
if (acceptEncoding.includes('gzip')) {
res.setHeader('Content-Encoding', 'gzip');
stream.pipe(zlib.createGzip()).pipe(res);
} else {
stream.pipe(res);
}
const http = require('http');
const fs = require('fs');
const path = require('path');
const mime = require('mime-types');
const zlib = require('zlib');
const PORT = 3000;
const PUBLIC_DIR = path.join(__dirname, 'public');
const server = http.createServer((req, res) => {
let filePath = path.join(
PUBLIC_DIR,
req.url === '/' ? 'index.html' : req.url
);
// 安全校验
filePath = path.normalize(filePath);
if (!filePath.startsWith(PUBLIC_DIR)) {
res.statusCode = 403;
return res.end('Forbidden');
}
// 设置Content-Type
const contentType = mime.lookup(filePath) || 'application/octet-stream';
res.setHeader('Content-Type', contentType);
// 缓存控制
res.setHeader('Cache-Control', 'public, max-age=3600');
const stream = fs.createReadStream(filePath);
stream.on('error', (err) => {
if (err.code === 'ENOENT') {
res.statusCode = 404;
res.end('Not Found');
} else {
res.statusCode = 500;
res.end('Server Error');
}
});
// 压缩支持
const acceptEncoding = req.headers['accept-encoding'] || '';
if (acceptEncoding.includes('gzip')) {
res.setHeader('Content-Encoding', 'gzip');
stream.pipe(zlib.createGzip()).pipe(res);
} else {
stream.pipe(res);
}
});
server.listen(PORT, () => {
console.log(`Static server running at http://localhost:${PORT}`);
});
创建public
目录和测试文件:
mkdir public
echo '<h1>Welcome</h1>' > public/index.html
启动服务器:
node server.js
访问测试:
http://localhost:3000
显示index.htmlhttp://localhost:3000/不存在的文件
返回404https
模块支持dotenv
管理配置通过这个约100行的实现,我们完成了支持缓存、压缩、安全校验的静态服务器。虽然不如专业框架强大,但理解了核心原理后,你能更好地驾驭上层框架。建议尝试继续扩展功能,比如添加Range请求支持或ETag验证。
完整项目代码可参考:GitHub示例仓库 “`
(注:实际字符数约1500字,可根据需要调整内容细节)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。