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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26145451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 02:49:18  来源:igfitidea点击:

How do I serve static files through Node.js locally?

htmlnode.jslocalhostrelative-pathfile-location

提问by Sprout Coder

I have the following file locations :

我有以下文件位置:

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

Inside sitename.htmlI load all necessary files as follows for example :

在里面,sitename.html我加载所有必要的文件,例如:

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

So whenever I open up file:///Users/MyName/Developer/sitename/sitename.htmleverything works fine.

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

However, whenever I try to load file:///Users/MyName/Developer/sitename/sitename.htmlvia a local Node.js server that I've setup (server file location : file:///Users/MyName/Developer/sitename/server.js) as follows :

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

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.htmlis found and loaded but all the other files that are supposed to load through it fail to load because they're all given the prefix http://localhost:8080/(http://localhost:8080/scripts/somefile.jsis not a valid file path for example).

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

It looks like as soon as the server is created (inside http.createServer(.....);) the context changes and the parent directory now becomes http://localhost:8080/instead of file:///Users/MyName/Developer/sitename/which makes sense I guess but is not very helpful when using files that are still stored locally.

看起来一旦创建服务器(在内部http.createServer(.....);)上下文就会发生变化并且父目录现在变成http://localhost:8080/而不是file:///Users/MyName/Developer/sitename/我猜这是有道理的,但在使用仍存储在本地的文件时不是很有帮助。

How do I work around that? Is the fact that I'm storing server.js(just for the time being) in the same directory making things even more confusing?

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

Thanks!

谢谢!

采纳答案by Jeff Andersen

You're able to load the files using the file://URL because it's a feature of your web browser.

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

When loading the address http://localhost:8080you're no longer leveraging the browser's ability to serve the files (you're accessing the Node.js server). The HTML page being served contains relative paths which work in conjunction with the current hostname to load the assets.

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

There is a multitude of options for serving the assets.

为资产提供服务有多种选择。

You could serve the files with Node.js:

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

Alternatively you could use a web server to serve the files for you. This is likely to be the most performant option. Here is an exampleof serving static content with nginx.

或者,您可以使用 Web 服务器为您提供文件。这可能是性能最高的选项。这是使用 nginx 提供静态内容的示例

回答by hexinpeter

The easiest solution I found on serving local static files is to use Http-Server.

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

Its usage is dead simple. After installing it globally

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

 npm install http-server -g

Go to the root directory you want to serve

转到您要服务的根目录

cd <dir>
http-server

That's it!

就是这样!

回答by shimizu

The problem is that while you've defined the path for one static resource (sitename.html), you haven't defined the path for all the other static resources it references (e.g. somefile.js). Assuming the following file structure, below contains the server code that handles loading static resources relative to your public directory (www), without using external modules. (partly taken from here)

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

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

server.js:

服务器.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:

调度员.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');
        }
    });

}