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

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

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

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行。

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

答案

您可以将ConnectServeStatic与 Node.js 结合使用:

  1. 使用 NPM 安装连接和服务静态

    $ npm install connect serve-static
  2. 创建具有以下内容的 server.js 文件:

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

    $ node server.js

您现在可以转到http://localhost:8080/yourfile.html

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

$ npm install http-server -g

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

$ cd MyApp

$ http-server

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

$ npx http-server

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

$ http-server -o --cors

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

$ http-server --help

还有许多其他不错的功能以及可以简单地部署到 NodeJitsu 的功能。

功能叉

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

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

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

$ npm install -g light-server 
$ light-server

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

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

简单的 JSON REST 服务器

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

自动刷新编辑器

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

我将Live Server与 Visual Studio Code 一起使用。

开源文本编辑器Brackets还包括一个 NodeJS 静态 Web 服务器。只需在 Brackets 中打开任何 HTML 文件,然后按 “ 实时预览 ”,它就会启动静态服务器并在该页面上打开浏览器。只要您编辑和保存 HTML 文件,浏览器就会自动刷新。这在测试自适应网站时特别有用。在多个浏览器 / 窗口大小 / 设备上打开 HTML 页面。保存您的 HTML 页面,并立即查看您的自适应内容是否正常运行,因为它们全部自动刷新。

PhoneGap 开发人员

如果您要编写混合移动应用程序的代码 ,您可能想知道PhoneGap团队在其新的PhoneGap App 中采用了此自动刷新概念。这是一个通用的移动应用程序,可以在开发过程中从服务器加载 HTML5 文件。这是一个非常巧妙的技巧,因为如果您要更改 JS / CSS / HTML 文件,则现在可以在混合移动应用程序的开发周期中跳过缓慢的编译 / 部署步骤,而这通常是您的大部分时间。它们还提供检测文件更改的静态phonegap serve 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 静态文件 Web 服务器。将其放在路径中以启动任何目录中的服务器,并带有可选的 port 参数。

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\n");
      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 + "\n");
        response.end();
        return;
      }

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

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

更新资料

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

代码的问题是,您总是返回 “文本 / 纯文本” 的内容类型。上面的代码不返回任何内容类型,但是如果您仅将其用于 HTML,CSS 和 JS,则浏览器可以推断出它们的类型。 没有内容类型比错误类型更好。

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

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

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\n");
      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 + "\n");
        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\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");

您不需要快递。您不需要连接。 Node.js 会原生进行 http 操作。您需要做的就是根据请求返回一个文件:

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)

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

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)

我认为您现在缺少的部分是您正在发送:

Content-Type: text/plain

如果要使用 Web 浏览器呈现 HTML,则应将其更改为:

Content-Type: text/html

步骤 1(在命令提示符内 [希望您 CD 到您的文件夹]): npm install express

步骤 2:建立档案 server.js

var fs = require("fs");
var host = "127.0.0.1";
var port = 1337;
var express = require("express");

var app = express();
app.use(express.static(__dirname + "/public")); //use static files in ROOT/public folder

app.get("/", function(request, response){ //root dir
    response.send("Hello!!");
});

app.listen(port, host);

请注意,您也应该添加 WATCHFILE(或使用 nodemon)。上面的代码仅适用于简单的连接服务器。

步骤 3: node server.jsnodemon server.js

如果您只想托管简单的 HTTP 服务器,则现在有一种更简单的方法。 npm install -g http-server

并打开目录并输入http-server

https://www.npmjs.org/package/http-server

快速方法:

var express = require('express');
var app = express();
app.use('/', express.static(__dirname + '/../public')); // ← adjust
app.listen(3000, function() { console.log('listening'); });

你的方式:

var http = require('http');
var fs = require('fs');

http.createServer(function (req, res) {
    console.dir(req.url);

    // will get you  '/' or 'index.html' or 'css/styles.css' ...
    // • you need to isolate extension
    // • have a small mimetype lookup array/object
    // • only there and then reading the file
    // •  delivering it after setting the right content type

    res.writeHead(200, {'Content-Type': 'text/html'});

    res.end('ok');
}).listen(3001);

我认为,与其处理 switch 语句,不如从字典中查找内容类型:

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

...

    var contentType = contentTypesByExtension[fileExtension] || 'text/plain';

这基本上是连接版本 3 可接受答案的更新版本:

var connect = require('connect');
var serveStatic = require('serve-static');

var app = connect();

app.use(serveStatic(__dirname, {'index': ['index.html']}));
app.listen(3000);

我还添加了默认选项,以便将 index.html 用作默认值。

您无需使用任何 NPM 模块即可运行简单的服务器,Node 的库非常小,名为 “ NPM Free Server ”:

50 行代码,如果您请求文件或文件夹,则输出,如果工作失败,则将其显示为红色或绿色。小于 1KB(最小)。