});
}
}
module.exports = StaticServer;
在这个模块文件内,我们声明了一个StaticServer类,并给其定义了start方法,在该方法体内,创建了一个server对象,监听rquest事件,并将服务器绑定到配置文件指定的端口。在这个阶段,我们对于任何请求都暂时不作区分地简单地返回请求的文件路径。path模块用来规范化连接和解析路径,这样我们就不用特意来处理操作系统间的差异。
app.js
const StaticServer = require('./static-server');
(new StaticServer()).start();在这个文件内,调用上面的static-server模块,并创建一个StaticServer实例,调用其start方法,启动了一个静态资源服务器。这个文件后面将不需要做其他修改,所有对静态资源服务器的完善都发生在static-server.js内。
在目录下启动程序会看到成功启动的log:
> node app.js
Server started on port 9527在浏览器中访问,可以看到服务器将请求路径直接返回了。

路由处理
之前我们对任何请求都只是向客户端返回文件位置而已,现在我们将其替换成返回真正的文件:
routeHandler(pathName, req, res) {
}
start() {
http.createServer((req, res) => {
const pathName = path.join(this.root, path.normalize(req.url));
this.routeHandler(pathName, req, res);
}).listen(this.port, err => {
...
});
}将由routeHandler来处理文件发送。
读取静态文件
读取文件之前,用fs.stat检测文件是否存在,如果文件不存在,回调函数会接收到错误,发送404响应.
respondNotFound(req, res) {
res.writeHead(404, {
'Content-Type': 'text/html'
});
res.end(`<h1>Not Found</h1><p>The requested URL ${req.url} was not found on this server.</p>`);
} respondFile(pathName, req, res) {
const readStream = fs.createReadStream(pathName);
readStream.pipe(res);
}
routeHandler(pathName, req, res) {
fs.stat(pathName, (err, stat) => {
if (!err) {
this.respondFile(pathName, req, res);
} else {
this.respondNotFound(req, res);
}
});
}
Note:
读取文件,这里用的是流的形式createReadStream而不是readFile,是因为后者会在得到完整文件内容之前将其先读到内存里。这样万一文件很大,再遇上多个请求同时访问,readFile就承受不来了。使用文件可读流,服务端不用等到数据完全加载到内存再发回给客户端,而是一边读一边发送分块响应。这时响应里会包含如下响应头:









