文件服务器

    让我们继续扩展一下上面的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

    文件服务器 - 图1

    只要当前目录下存在文件 index.html ,服务器就可以把文件内容发送给浏览器。观察控制台输出:

    200 /index.html

    200 cssuikit.min.css

    200 jsjquery.min.js

    200 fontsfontawesome-webfont.woff2

    第一个请求是浏览器请求 index.html 页面,后续请求是浏览器解析HTML后发送的其它资源请求。