如何在本地通过 Node.js 提供静态文件?

Posted

技术标签:

【中文标题】如何在本地通过 Node.js 提供静态文件?【英文标题】:How do I serve static files through Node.js locally? 【发布时间】:2014-11-26 12:50:08 【问题描述】:

我有以下文件位置:

file:///Users/MyName/Developer/sitename/scripts (contains all .js files..)
file:///Users/MyName/Developer/sitename/css (contains all .css files..)
file:///Users/MyName/Developer/sitename/images (contains all .jpg/png/etc. files..)
file:///Users/MyName/Developer/sitename/sitename.html
file:///Users/MyName/Developer/sitename/server.js

sitename.html 中,我加载了所有必要的文件,例如:

<html>
  <head>
    <script src="scripts/somefile.js"></script>
  </head>
  ...
</html>

所以每当我打开file:///Users/MyName/Developer/sitename/sitename.html 时,一切正常。

但是,每当我尝试通过我设置的本地 Node.js 服务器(服务器文件位置:file:///Users/MyName/Developer/sitename/server.js)加载 file:///Users/MyName/Developer/sitename/sitename.html 时,如下所示:

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

fs.readFile('./sitename.html', function (err, html) 

    if (err) throw err; 

    http.createServer(function (request,response)
      
        // serve site
        if (request.url === "/")
        
            response.writeHeader(200, "Content-Type": "text/html");  
            response.write(html);  
        
        response.end(); 
    ).listen(8080); 
);

sitename.html 已找到并已加载,但所有其他应该通过它加载的文件都无法加载,因为它们都被赋予了前缀 http://localhost:8080/(例如,http://localhost:8080/scripts/somefile.js 不是有效的文件路径)。

看起来只要创建服务器(在http.createServer(.....); 内),上下文就会发生变化,父目录现在变为http://localhost:8080/ 而不是file:///Users/MyName/Developer/sitename/,我猜这很有意义,但在使用以下文件时不是很有帮助仍然存储在本地。

我该如何解决这个问题?我将server.js(暂时)存储在同一个目录中这一事实是否会让事情变得更加混乱?

谢谢!

【问题讨论】:

【参考方案1】:

我在提供本地静态文件时发现的最简单的解决方案是使用Http-Server。

它的用法非常简单。全局安装后

 npm install http-server -g

转到您要服务的根目录

cd <dir>
http-server

就是这样!

【讨论】:

这对我来说非常有效,我相信这正是 OP 正在寻找的解决方案!谢谢@hexinpeter【参考方案2】:

问题在于,虽然您已经为一个静态资源 (sitename.html) 定义了路径,但您还没有为它引用的所有其他静态资源 (例如 somefile.js) 定义路径。假设以下文件结构,下面包含处理加载相对于您的公共目录 (www) 的静态资源的服务器代码,而不使用外部模块。 (部分取自here)

project/
    server/    
        server.js
        dispatcher.js
    www/
        index.html
        js/ (your javascript files)
        css/ (your css files)

server.js

var http = require('http');
http.createServer(handleRequest).listen(8124, "127.0.0.1");
var dispatcher = require('./dispatcher.js');

function handleRequest(req, res) 
    try 
        console.log(req.url);
        dispatcher.dispatch(req, res);
     catch(err) 
        console.log(err);
    

dispatcher.js

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

this.dispatch = function(request, response) 
    //set the base path so files are served relative to index.html
    var basePath = "../www";
    var filePath = basePath + request.url;

    var contentType = 'text/html';
    var extname = path.extname('filePath');
    //get right Content-Type
    switch (extname) 
        case '.js':
            contentType = 'text/javascript';
            break;
        case '.css':
            contentType = 'text/css';
            break;
    

    //default to index.html
    if (filePath == basePath + "/") 
        filePath = filePath + "index.html";
    

    //Write the file to response
    fs.readFile(filePath, function(error, content) 
        if (error) 
            response.writeHead(500);
            response.end();
         else 
            response.writeHead(200, 'Content-Type': contentType);
            response.end(content, 'utf-8');
        
    );


【讨论】:

【参考方案3】:

您可以使用file:// URL 加载文件,因为这是您的网络浏览器的一项功能。

加载地址 http://localhost:8080 时,您不再利用浏览器提供文件的能力(您正在访问 Node.js 服务器)。提供的 HTML 页面包含与当前主机名一起加载资产的相对路径。

服务资产有多种选择。

您可以使用 Node.js 提供文件:

Express.js 有一个serving static assets 的模块 Node-static 是我在 npm 上快速搜索找到的一个模块

或者,您可以使用网络服务器为您提供文件。这可能是性能最高的选项。 Here is an example 使用 nginx 提供静态内容。

【讨论】:

您好,非常感谢您的回复。我会看看你建议的那两个选项。但是仅仅因为我是新手,请您详细说明一下:因此,每当有人构建 Web 应用程序并使用 Node.js 为该应用程序提供服务,并且该应用程序有很多静态文件(显然)时,这是否意味着在本地测试他们的应用程序时,他们总是需要像您建议的那样使用“插件”吗?看起来有点奇怪,不是吗,Node 没有默认选项来指定将提供的所有静态文件的父文件夹位置。?再次感谢您的帮助! Node 为您提供了提供这些文件的工具,您只需实现它。这就是为什么存在这么多模块的原因,因为功能并不是开箱即用的。您绝对可以使用 Node.js 提供文件,但您必须在服务器中实现一个路由,以识别对“/style.css”的请求并让它从磁盘读取该文件。 非常感谢您澄清 Jeff

以上是关于如何在本地通过 Node.js 提供静态文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 node.js 在 html 中包含静态文件

Node.js 公共静态文件夹,用于为 js 提供 utf-8 字符集

Node.js Express js在较大文件上提供静态文件的速度非常慢

使用 restify (node.js) 提供静态文件

为啥我在 node.js 中使用 sendFile() 方法为两个路由提供静态文件时会出错

使用 Node JS / Express 提供包含图像的静态 HTML 页面