web-dev-qa-db-ja.com

Node.jsを介してローカルで静的ファイルを提供するにはどうすればよいですか?

私は次のファイルの場所を持っています:

_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/sitename.html_)を介して_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.html_が見つかり、ロードされますが、ロードすることになっている他のすべてのファイルにはプレフィックス_http://localhost:8080/_が付けられているため、ロードに失敗します(_http://localhost:8080/scripts/somefile.js_は有効なファイルパスではありません。 )。

サーバーが作成されるとすぐに(http.createServer(.....);内で)コンテキストが変更され、親ディレクトリが_http://localhost:8080/_ではなく_file:///Users/MyName/Developer/sitename/_になるように見えます。これは理にかなっていますが、あまり意味がありません。ローカルに保存されているファイルを使用する場合に役立ちます。

どうすればそれを回避できますか? _server.js_を(とりあえず)同じディレクトリに保存しているという事実は、事態をさらに混乱させていますか?

ありがとう!

10
Sprout Coder

Webブラウザの機能であるため、file://URLを使用してファイルをロードできます。

アドレスhttp://localhost:8080をロードすると、ファイルを提供するブラウザーの機能を利用できなくなります(Node.jsサーバーにアクセスします)。提供されるHTMLページには、現在のホスト名と連携してアセットをロードする相対パスが含まれています。

アセットを提供するためのオプションは多数あります。

Node.jsでファイルを提供できます。

または、Webサーバーを使用してファイルを提供することもできます。これは、最もパフォーマンスの高いオプションである可能性があります。 ここに例があります nginxで静的コンテンツを提供します。

8
Jeff Andersen

ローカル静的ファイルの提供で私が見つけた最も簡単な解決策は、 Http-Server を使用することです。

その使い方はとても簡単です。グローバルにインストールした後

 npm install http-server -g

提供するルートディレクトリに移動します

cd <dir>
http-server

それでおしまい!

20
hexinpeter

問題は、1つの静的リソース(sitename.html)のパスを定義しているのに、それが参照する他のすべての静的リソース(somefile.jsなど)のパスを定義していないことです。次のファイル構造を想定すると、以下には、外部モジュールを使用せずに、パブリックディレクトリ(www)に関連する静的リソースの読み込みを処理するサーバーコードが含まれています。 (一部は ここ から取得)

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
shimizu