我想运行一个非常简单的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);



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

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

评论

看一下npm模块的“连接”。它提供了这种基本功能,并且是许多设置和其他程序包的基础。

您应该将解决方案作为答案并将其标记为正确。

我能够通过Eric B. Sowell找到一个完美的解决方案。Sowell称为“从节点js提供静态文件”。阅读全部内容。强烈推荐。

看看我编写的名为Cachemere的模块。它还会自动缓存所有资源。 github.com/topcloud/cachemere

本地网络服务器是一个很好的例子,

#1 楼

最简单的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的功能。

功能叉

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


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

Light Server:一种自动刷新的替代方法

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代码一起使用。

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

PhoneGap开发人员

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

PhoneGap + Sencha Touch开发人员

我现在已经广泛采用了PhoneGap静态服务器和PhoneGap。 Sencha Touch和jQuery Mobile开发人员的开发人员应用程序。在Sencha Touch Live上检查一下。支持--qr QR代码和--localtunnel,可将您的静态服务器从台式机代理到防火墙之外的URL!大量使用。大大提高了混合移动开发人员的速度。

Cordova + Ionic Framework开发人员

本地服务器和自动刷新功能已纳入ionic工具。只需从您的应用程序文件夹中运行ionic serve。甚至更好... ionic serve --lab可以同时查看iOS和Android的自动刷新视图。

评论


npm如果需要同样的东西,请安装live-server -g,但是在检测到文件更改时自动重新加载

–user993683
15年5月14日在14:18

一个小“陷阱”-。默认情况下,http服务器在0.0.0.0上提供站点服务。因此,您必须指定一个IP地址以使其能够作为本地测试服务器正常工作:http-server -a localhost

–JESii
2015年6月11日在12:02



是的... 0.0.0.0将使其绑定到所有IP网络设备(WiFi,电缆,蓝牙)的所有IP,在任何公共网络上都是一个坏主意,因为您可能会遭到黑客攻击。如果您只想在安全的防火墙网络中演示您的应用程序以向他人展示或将其连接到同一网络上的移动设备,那还不错。

–托尼·奥哈根(Tony O'Hagan)
2015年6月12日在2:20



真正有用的小工具。我的服务器上运行着许多Node应用程序,因此我添加了“ -p”选项来选择8080以外的端口。例如:nohup http-server -p 60080&(在后台启动它,并让您与shell会话。)您应该确保端口对世界开放,例如:iptables -I INPUT 1 -p tcp --dport 60090 -j ACCEPT(在许多Linux系统上)

–水泡花生
17年12月11日在22:57



如何将其作为服务运行,因此即使关闭命令提示符也可以使用它。如果没有这个工具,有没有提供这种工具。

–山地沙质
19年8月9日在7:59

#2 楼

您可以为此使用Node.js的Connect and ServeStatic:



通过NPM安装connect and serve-static

$ npm install connect serve-static



使用以下内容创建server.js文件:

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

connect()
    .use(serveStatic(__dirname))
    .listen(8080, () => console.log('Server running on 8080...'));



使用Node.js运行

$ node server.js



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

评论


出于教育方面的考虑,该想法是不使用现有的库,但我认为使用Express比其较低版本的Connect更好。

–偶像
2011-12-8 14:33

Express提供静态文件的部分只是Connect,所以我看不到使用Express提供静态文件的原因。但是是的,Express也可以做。

–吉安·马可(Gian Marco)
2011年12月9日在8:57

极好的建议。上面的步骤非常适合我的目的。感谢Gian,这是Express的链接,它显示了它是基于Connect,expressjs.com构建的。这是Express的使用方法:expressjs.com/guide.html

–杰克·斯通(Jack Stone)
2012年6月25日在3:04

无法为我工作,结果无法获取/test.html。我应该用目录名替换__dirname吗?

– Timo
13-10-26在10:04

现在,connect已更改为版本3。因此,必须使用mistatic所描述的serve-static。我发布了另一个带有连接v3完整代码的答案。

– tomet
14年6月20日在17:38

#3 楼

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


Node.JS静态文件Web服务器。将其放在路径中以启动任何目录中的服务器,并使用可选的端口参数。


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");


Update

要点确实处理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");


评论


这并不能真正解决“问题”。您将index.html作为二进制文件返回,并且不处理CSS和JS。

–偶像
2012年11月30日4:58

它确实处理css和js。它不会以二进制文件形式返回index.html。它只是以任何格式将数据复制到磁盘上。请参阅更新以获取更多说明。

–乔纳森·特兰(Jonathan Tran)
2012年11月30日16:56

代码的一个问题,区分大小写,在某些文件的Unix上,它给出404

– Pradeep
13年11月15日在9:47

请注意,“ path.exists和path.existsSync现在已被弃用。请使用fs.exists和fs.existsSync。” stackoverflow.com/a/5008295/259

–大卫·赛克斯(David Sykes)
2015年4月3日,14:26

请注意,fs.exists()也已弃用。在fs.stat()上捕获错误,而不是创建竞争条件。

–马特
17年2月1日在5:26

#4 楼

您不需要快递。您不需要连接。 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)


评论


如果我没记错的话,此解决方案将不处理编码类型,因此对HTML页面和图像的请求将获得相同的编码。是不是

–偶像
14-10-14在12:06

@idophir大多数情况下,编码都无关紧要,浏览器会根据所使用的html标签或其他信息来推断出编码,或者他们猜得很好。就像上面提到的某人一样,没有MIME类型总比错误类型好。您当然可以使用诸如node-mime之类的东西来找出文件的mime类型,但是完全符合Web的http服务器不在此问题范围之内。

– B T
14-10-14在18:07



@Rooster您不需要任何特殊的东西-只需节点thisfile.js。它会运行,监听新的连接并返回新的结果,直到A.被信号关闭或B.某些疯狂的错误导致程序终止。

– B T
15年3月18日在1:32

@Rooster在github.com/Unitech/pm2中找到了另一个臭名昭著的守护进程。

–行人
2015年5月9日16:32

我最喜欢这个答案,但是有两个问题:1)当它应该返回404时返回200。要修复,我在“打开”回调中调用writeHead(200)。 2)如果有错误,则插座保持打开状态;修复我在“错误”回调中调用response.destroy()的问题。

– Paul Brannan
17年8月14日在21:03

#5 楼

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

Content-Type: text/plain


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

Content-Type: text/html


评论


感谢您的快速回复。现在,该页面已加载,但没有CSS。如何获得加载了CSS和JS的标准html页面?

–偶像
2011年5月21日在21:22



您需要开始扩展该服务器。现在,它只知道如何提供index.html-您需要教它如何通过自己的适当MIME类型为foo.css和foo.js提供服务。

–clee
2011年5月21日在22:06

如果您不想提供静态文件,则可以将CSS放入