文件服务器
让我们继续扩展一下上面的Web程序。我们可以设定一个目录,然后让Web程序变成一个文件服务器。要实现这一点,我们只需要解析 request.url 中的路径,然后在本地找到对应的文件,把文件内容发送出去就可以了。
解析URL需要用到Node.js提供的 url 模块,它使用起来非常简单,通过 parse() 将一个字符串解析为一个 Url 对象:
'use strict';
var url = require('url');
console.log(url.parse('http://user:pass@host.com:8080pathto/file?query=string#hash'));
结果如下:
Url {
protocol: 'http:',
slashes: true,
auth: 'user:pass',
host: 'host.com:8080',
port: '8080',
hostname: 'host.com',
hash: '#hash',
search: '?query=string',
query: 'query=string',
pathname: 'pathto/file',
path: 'pathto/file?query=string',
href: 'http://user:pass@host.com:8080pathto/file?query=string#hash' }
处理本地文件目录需要使用Node.js提供的 path 模块,它可以方便地构造目录:
'use strict';
var path = require('path');
// 解析当前目录:
var workDir = path.resolve('.'); // 'Usersmichael'
// 组合完整的文件路径:当前目录+'pub'+'index.html':
var filePath = path.join(workDir, 'pub', 'index.html');
// 'Usersmichael/pub/index.html'
使用 path 模块可以正确处理操作系统相关的文件路径。在Windows系统下,返回的路径类似于 C:\Users\michael\static\index.html ,这样,我们就不关心怎么拼接路径了。
最后,我们实现一个文件服务器 file_server.js :
'use strict';
var
fs = require('fs'),
url = require('url'),
path = require('path'),
http = require('http');
// 从命令行参数获取root目录,默认是当前目录:
var root = path.resolve(process.argv[2] || '.');
console.log('Static root dir: ' + root);
// 创建服务器:
var server = http.createServer(function (request, response) {
// 获得URL的path,类似 'cssbootstrap.css':
var pathname = url.parse(request.url).pathname;
// 获得对应的本地文件路径,类似 'srvwwwcssbootstrap.css':
var filepath = path.join(root, pathname);
// 获取文件状态:
fs.stat(filepath, function (err, stats) {
if (!err && stats.isFile()) {
// 没有出错并且文件存在:
console.log('200 ' + request.url);
// 发送200响应:
response.writeHead(200);
// 将文件流导向response:
fs.createReadStream(filepath).pipe(response);
} else {
// 出错了或者文件不存在:
console.log('404 ' + request.url);
// 发送404响应:
response.writeHead(404);
response.end('404 Not Found');
}
});
});
server.listen(8080);
console.log('Server is running at http://127.0.0.1:8080/');
没有必要手动读取文件内容。由于 response 对象本身是一个 Writable Stream ,直接用 pipe() 方法就实现了自动读取文件内容并输出到HTTP响应。
在命令行运行 node file_server.js pathto/dir ,把 pathto/dir 改成你本地的一个有效的目录,然后在浏览器中输入 http://localhost:8080/index.html :
只要当前目录下存在文件 index.html ,服务器就可以把文件内容发送给浏览器。观察控制台输出:
200 /index.html
200 cssuikit.min.css
200 jsjquery.min.js
200 fontsfontawesome-webfont.woff2
第一个请求是浏览器请求 index.html 页面,后续请求是浏览器解析HTML后发送的其它资源请求。