使用node.js作为简单的Web服务器

Using node.js as a simple web server

我想运行一个非常简单的HTTP服务器。 对example.com的每个GET请求都应该为它提供index.html,但是作为常规HTML页面(即,与您阅读普通网页时相同的体验)。

使用下面的代码,我可以阅读index.html的内容。 如何将index.html作为常规网页提供?

1
2
3
4
5
6
7
8
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(index);
}).listen(9615);

下面的一个建议很复杂,需要我为我想要使用的每个资源(CSS,JavaScript,图像)文件写一个get行。

如何使用一些图像,CSS和JavaScript提供单个HTML页面?


您可以将Connect和ServeStatic与Node.js一起使用:

  • 使用NPM安装connect和serve-static

    1
    $ npm install connect serve-static
  • 使用此内容创建server.js文件:

    1
    2
    3
    4
    5
    var connect = require('connect');
    var serveStatic = require('serve-static');
    connect().use(serveStatic(__dirname)).listen(8080, function(){
        console.log('Server running on 8080...');
    });
  • 使用Node.js运行

    1
    $ node server.js
  • 您现在可以转到http://localhost:8080/yourfile.html


    最简单的Node.js服务器就是:

    1
    $ npm install http-server -g

    现在,您可以通过以下命令运行服务器:

    1
    2
    3
    $ cd MyApp

    $ http-server

    如果您使用的是NPM 5.2.0或更高版本,则可以使用http-server而不使用npx进行安装。建议不要将其用于生产,但这是快速获取在localhost上运行的服务器的好方法。

    1
    $ npx http-server

    或者,您可以尝试这样做,这将打开您的Web浏览器并启用CORS请求:

    1
    $ http-server -o --cors

    有关更多选项,请查看GitHub上http-server的文档,或运行:

    1
    $ http-server --help

    很多其他不错的功能和对NodeJitsu的脑死亡简单部署。

    功能分叉

    当然,您可以使用自己的fork轻松实现功能。你可能会发现它已经在这个项目现有的800多个分支中完成:

    • https://github.com/nodeapps/http-server/network

    轻型服务器:自动刷新替代方案

    http-server的一个很好的替代是light-server。它支持文件监视和自动刷新以及许多其他功能。

    1
    2
    $ npm install -g light-server
    $ light-server

    在Windows资源管理器中添加到目录上下文菜单

    1
    2
     reg.exe add HKCR\Directory\shell\LightServer\command /ve /t REG_EXPAND_SZ /f /d""C:
    odejs\light-server.cmd" "-o" "-s" "%V""

    简单的JSON REST服务器

    如果您需要为原型项目创建一个简单的REST服务器,那么json-server可能就是您正在寻找的。

    自动刷新编辑器

    大多数网页编辑器和IDE工具现在都包含一个Web服务器,它将监视您的源文件并在更改时自动刷新您的网页。

    我使用Live Server与Visual Studio代码。

    开源文本编辑器Brackets还包括一个NodeJS静态Web服务器。只需在Brackets中打开任何HTML文件,按"实时预览"即可启动静态服务器并在页面上打开浏览器。每当您编辑和保存HTML文件时,浏览器都会自动刷新。这在测试自适应网站时尤其有用。在多个浏览器/窗口大小/设备上打开HTML页面。保存您的HTML页面,并立即查看您的自适应内容是否正常工作,因为它们都会自动刷新。

    PhoneGap开发人员

    如果您正在编写混合移动应用程序,您可能有兴趣知道PhoneGap团队使用他们的新PhoneGap应用程序采用了这种自动刷新概念。这是一个通用的移动应用程序,可以在开发期间从服务器加载HTML5文件。这是一个非常流畅的技巧,因为现在你可以跳过混合移动应用程序的开发周期中的慢速编译/部署步骤,如果你要更改JS / CSS / HTML文件 - 这是你大部分时间都在做的事情。它们还提供检测文件更改的静态NodeJS Web服务器(运行phonegap serve)。

    PhoneGap + Sencha Touch开发者

    我现在已经为Sencha Touch和jQuery Mobile开发人员广泛调整了PhoneGap静态服务器和PhoneGap开发者应用程序。在Sencha Touch Live上查看。支持--qr QR码和--localtunnel,它将您的静态服务器从您的台式计算机代理到防火墙外的URL!吨的用途。混合移动设备的大规模加速。

    Cordova + Ionic框架开发人员

    本地服务器和自动刷新功能将附加到ionic工具中。只需从您的应用程序文件夹中运行ionic serve即可。更好...... ionic serve --lab可以查看iOS和Android的自动刷新并排视图。


    看看这个要点。我在这里复制它以供参考,但要点已经定期更新。

    Node.JS static file web server. Put it in your path to fire up servers in any directory, takes an optional port argument.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    var http = require("http"),
        url = require("url"),
        path = require("path"),
        fs = require("fs"),
        port = process.argv[2] || 8888;

    http.createServer(function(request, response) {

      var uri = url.parse(request.url).pathname
        , filename = path.join(process.cwd(), uri);

      fs.exists(filename, function(exists) {
        if(!exists) {
          response.writeHead(404, {"Content-Type":"text/plain"});
          response.write("404 Not Found
    ");
          response.end();
          return;
        }

        if (fs.statSync(filename).isDirectory()) filename += '/index.html';

        fs.readFile(filename,"binary", function(err, file) {
          if(err) {        
            response.writeHead(500, {"Content-Type":"text/plain"});
            response.write(err +"
    ");
            response.end();
            return;
          }

          response.writeHead(200);
          response.write(file,"binary");
          response.end();
        });
      });
    }).listen(parseInt(port, 10));

    console.log("Static file server running at
      => http://localhost:" + port +"/
    CTRL + C to shutdown");

    更新

    gist确实处理css和js文件。我自己用过它。在"二进制"模式下使用读/写不是问题。这只意味着文件不会被文件库解释为文本,并且与响应中返回的内容类型无关。

    您的代码的问题是您总是返回内容类型的"text / plain"。上面的代码不会返回任何内容类型,但是如果您只是将它用于HTML,CSS和JS,那么浏览器可以推断出那些就好了。没有内容类型比错误的更好。

    通常,内容类型是Web服务器的配置。所以我很抱歉,如果这不能解决您的问题,但它对我来说是一个简单的开发服务器,并认为它可能会帮助其他人。如果确实需要在响应中使用正确的内容类型,则需要将它们显式定义为joeytwiddle,或使用具有合理默认值的Connect之类的库。关于这一点的好处是它简单且独立(没有依赖)。

    但我确实感觉到了你的问题。所以这是组合的解决方案。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    var http = require("http"),
        url = require("url"),
        path = require("path"),
        fs = require("fs")
        port = process.argv[2] || 8888;

    http.createServer(function(request, response) {

      var uri = url.parse(request.url).pathname
        , filename = path.join(process.cwd(), uri);

      var contentTypesByExtension = {
        '.html':"text/html",
        '.css': "text/css",
        '.js':  "text/javascript"
      };

      fs.exists(filename, function(exists) {
        if(!exists) {
          response.writeHead(404, {"Content-Type":"text/plain"});
          response.write("404 Not Found
    ");
          response.end();
          return;
        }

        if (fs.statSync(filename).isDirectory()) filename += '/index.html';

        fs.readFile(filename,"binary", function(err, file) {
          if(err) {        
            response.writeHead(500, {"Content-Type":"text/plain"});
            response.write(err +"
    ");
            response.end();
            return;
          }

          var headers = {};
          var contentType = contentTypesByExtension[path.extname(filename)];
          if (contentType) headers["Content-Type"] = contentType;
          response.writeHead(200, headers);
          response.write(file,"binary");
          response.end();
        });
      });
    }).listen(parseInt(port, 10));

    console.log("Static file server running at
      => http://localhost:" + port +"/
    CTRL + C to shutdown");


    你不需要快递。你不需要连接。 Node.js确实是http NATIVELY。您需要做的就是根据请求返回一个文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var http = require('http')
    var url = require('url')
    var fs = require('fs')

    http.createServer(function (request, response) {
        var requestUrl = url.parse(request.url)    
        response.writeHead(200)
        fs.createReadStream(requestUrl.pathname).pipe(response)  // do NOT use fs's sync methods ANYWHERE on production (e.g readFileSync)
    }).listen(9615)

    一个更完整的示例,可确保请求无法访问基目录下的文件,并进行正确的错误处理:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    var http = require('http')
    var url = require('url')
    var fs = require('fs')
    var path = require('path')
    var baseDirectory = __dirname   // or whatever base directory you want

    var port = 9615

    http.createServer(function (request, response) {
        try {
            var requestUrl = url.parse(request.url)

            // need to use path.normalize so people can't access directories underneath baseDirectory
            var fsPath = baseDirectory+path.normalize(requestUrl.pathname)

            var fileStream = fs.createReadStream(fsPath)
            fileStream.pipe(response)
            fileStream.on('open', function() {
                 response.writeHead(200)
            })
            fileStream.on('error',function(e) {
                 response.writeHead(404)     // assume the file doesn't exist
                 response.end()
            })
       } catch(e) {
            response.writeHead(500)
            response.end()     // end the response so browsers don't hang
            console.log(e.stack)
       }
    }).listen(port)

    console.log("listening on port"+port)


    我认为你现在缺少的那部分是你发送的:

    1
    Content-Type: text/plain

    如果您希望Web浏览器呈现HTML,则应将其更改为:

    1
    Content-Type: text/html