2013-03-20 4 views
3

J'avais l'impression que lorsque vous utilisez un serveur web nodejs, la racine du web est le dossier contenant le fichier js implémentant le serveur web. Donc si vous avez C: \ foo \ server.js et que vous l'exécutez, "/" fait référence à C: \ foo et "/index.htm" à C: \ foo \ index.htmnodejs web root

J'ai un fichier server.js avec un fichier frère default.htm, mais lorsque j'essaie de charger le contenu de /default.htm, le fichier est introuvable. Un chemin de fichier absolu fonctionne.

Où est "/" et que contrôle-t-il?


Travailler un repro Je l'ai simplifié à ceci:

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

et remarqué qu'il cherche ce

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

Alors "/" cartes à C: \

Existe-t-il un moyen de contrôler le mappage de la racine Web?


Je remarque que les chemins relatifs fonctionnent. Ainsi,

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

réussit. Je crois que ma confusion est née du placement accidentel des fichiers de projet de mon expérience originale à la racine d'un lecteur. Cela a permis des références à/default.htm pour résoudre correctement; Ce n'est que lorsque j'ai déplacé les éléments dans un dossier pour les placer sous le contrôle de la source que ce problème a été révélé.

Je vais certainement regarder en express, mais vous n'avez pas répondu à ma question: est-il possible de remapper la racine web et si oui comment?

En intérêt est ce server.js tel qu'il est actuellement

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/'); 

Je ne suis pas tout à fait certain de ce que vous entendez par « voies », mais je pense que setSettings et getsettings sont le genre de chose tu voulais dire, corrigez-moi si je me trompe. Nodejs ne semble pas prendre en charge le mappage arbitraire de la racine Web.

Tout ce qui est nécessaire est de préfixer chemins web absolus avec une période avant de les utiliser dans le système de fichiers:

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

Pouvez-vous publier le contenu du fichier server.js? –

Répondre

4

Alors que vous avez raison que la racine du serveur est le répertoire de travail courant Node .js n'effectuera pas de transfert direct vers les fichiers de votre système de fichiers, ce qui pourrait constituer un risque de sécurité après tout. A la place, vous devez lui fournir des routes qui, à leur tour, fournissent le contenu de la demande.

Un serveur simple comme

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

Est-ce que vous suffit de saisir toute demande et répondre de la même manière (mais ne lit pas le système de fichiers).

Maintenant, si vous voulez purger le contenu du fichier que vous devez spécifier une certaine façon de lire ce fichier dans le flux de réponse, cela peut se faire de plusieurs façons:

  1. Vous pouvez utiliser l'API fs pour trouver le fichier sur le disque, lire son contenu dans la mémoire, puis les rediriger vers la réponse. C'est une approche assez fastidieuse, surtout quand vous commencez à obtenir un plus grand nombre de fichiers, mais elle vous permet un contrôle très direct sur ce qui se passe dans votre application.
  2. Vous pouvez utiliser un serveur middleware comme express.js, lequel IMO est beaucoup mieux approche pour faire ce que vous voulez faire. Il y a beaucoup de questions et de réponses sur l'utilisation express ici sur StackOverflow, this is a good example of a static server qui est ce que vous parlez de

Modifier

Avec la clarification de la question de la raison:

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

Résultats de la pensée le fichier est à C:\default.htm est parce que vous utilisez un chemin absolu pas un chemin relatif. Si vous aviez:

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

Il sait alors que vous voulez opérer par rapport au répertoire de travail actuel. / est à partir de la racine de la partition et ./ est à partir du répertoire de travail en cours.

+0

Donc, en un mot, utilisez la syntaxe unix et la racine du web est la racine du lecteur contenant et il n'y a pas de mappage et ce n'est pas configurable? –

+0

Cela commence à avoir du sens. Je peux faire du remappage au niveau du système d'exploitation, donc il ne sert à rien de compliquer le serveur. Alors ils ont opté pour KISS. En fait, je l'ai fait la première fois sans m'en rendre compte, ce qui m'a troublé. –

+0

'readFile' et' readFileSync' sont simplement des lecteurs de système de fichiers. Ils ne sont pas strictement une chose web, car node.js n'est pas strictement un serveur web. – Joe