4

nodejs Webサーバーを実行すると、WebのルートはWebサーバーを実装するjsファイルを含むフォルダーであるという印象を受けました。したがって、C:\ foo \ server.jsがあり、それを実行すると、「/」はC:\ fooを参照し、「/ index.htm」はC:\ foo\index.htmにマップされます。

兄弟ファイルdefault.htmを含むファイルserver.jsがありますが、/ default.htmの内容を読み込もうとすると、ファイルが見つかりません。絶対ファイルパスが機能します。

「/」はどこにあり、何がこれを制御しますか?


再現を作成する私はそれをこれに単純化しました:

var fs = require('fs');
var body = fs.readFileSync('/default.htm');

これを探していることに気づきました

Error: ENOENT, no such file or directory 'C:\default.htm'

したがって、「/」はC:\にマップされます

Webルートのマッピングを制御する方法はありますか?


相対パスが機能していることに気付きました。それで

var fs = require('fs');
var body = fs.readFileSync('default.htm');

成功します。

私の混乱は、元の実験のプロジェクトファイルがドライブのルートに偶然に配置されたことから生じたと思います。これにより、/default.htmへの参照を正しく解決できました。この問題が明らかになったのは、ソース管理下に置くためにフォルダーに移動したときだけでした。

私は確かにエクスプレスを調べますが、あなたは私の質問に答えていません:ウェブルートを再マップすることは可能ですか?もしそうならどのように?

興味深いことに、これは現在のserver.jsです。

var http = require('http');
var fs = require('fs');
var sys = require('sys');
var formidable = require('formidable');
var util = require('util');
var URL = require('url');
var QueryString = require('querystring');
var mimeMap = { htm : "text/html", css : "text/css", json : "application/json" };
http.createServer(function (request, response) {
  var body, token, value, mimeType;
  var url = URL.parse(request.url);
  var path = url.pathname;
  var params = QueryString.parse(url.query);  
  console.log(request.method + " " + path);  
  switch (path) {
    case "/getsettings":
      try {
        mimeType = "application/json";
        body = fs.readFileSync("dummy.json"); //mock db 
      } catch(exception) {
        console.log(exception.text);
        body = exception;
      }
      break;  
    case "/setsettings":
      mimeType = "application/json";
      body="{}";
      console.log(params);
      break;  
    case "/": 
      path = "default.htm";
    default:
      try { 
        mimeType = mimeMap[path.substring(path.lastIndexOf('.') + 1)];
        if (mimeType) {
         body = fs.readFileSync(path);
        } else {
          mimeType = "text/html";
          body = "<h1>Error</h1><body>Could not resolve mime type from file extension</body>";
        }
      } catch (exception) {
        mimeType = "text/html";
        body = "<h1>404 - not found</h1>" + exception.toString();
      }
      break;
  }
  response.writeHead(200, {'Content-Type': mimeType});
  response.writeHead(200, {'Cache-Control': 'no-cache'});
  response.writeHead(200, {'Pragma': 'no-cache'});
  response.end(body);  
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');

「ルート」が何を意味するのか完全にはわかりませんが、setsettingsとgetsettingsはあなたが意図したようなものだと思います。間違っている場合は、訂正してください。


Nodejsは、Webルートの任意のマッピングをサポートしていないようです。

必要なのは、ファイルシステムで使用する前に絶対Webパスの前にピリオドを付けることだけです。

var URL = require('url');
var url = URL.parse(request.url);
var path = url.pathname;
if (path[0] == '/')
  path = '.' + path;
4

1 に答える 1

4

サーバーのルートが現在の作業ディレクトリであることは正しいですが、Node.jsはファイルシステム上のファイルへの直接パススルーを実行しません。これは、結局のところ、セキュリティ上のリスクになる可能性があります。

代わりに、ルートを提供する必要があります。ルートは、行われているリクエストのコンテンツを提供します。

のような単純なサーバー

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

リクエストをキャプチャて同じ方法で応答します(ただし、ファイルシステムは読み取りません)。

ここで、ファイルの内容を提供する場合は、そのファイルを応答ストリームに読み込む方法を指定する必要があります。これは、いくつかの方法で実行できます。

  1. APIを使用してfs、ディスク上のファイルを検索し、その内容をメモリに読み込んでから、応答にパイプで送信できます。これは、特に多数のファイルを取得し始める場合はかなり退屈なアプローチですが、アプリケーションで何が起こっているかを非常に直接制御できます。
  2. のようなミドルウェアサーバーを使用できますexpress.js。IMOは、やりたいことを実行するためのはるかに優れたアプローチです。StackOverflowでExpressを使用することについては、たくさんの質問と回答があります。これは、あなたが話している静的サーバーの良い例です。

編集

質問の明確化により、理由は次のとおりです。

var body = fs.readFileSync('/default.htm');

ファイルが存在すると考える結果は、相対パスではなく絶対パスC:\default.htmを使用しているためです。あなたが持っていた場合:

var body = fs.readFileSync('./default.htm');

次に、現在の作業ディレクトリを基準にして操作する必要があることがわかります。/パーティションのルートからのものであり./現在の作業ディレクトリからのものです。

于 2013-03-20T00:56:47.567 に答える