2012-08-26 24 views
19

Estoy tratando de aprender node.js y he golpeado un poco de una barricada.Node.js - archivos JS y CSS externos (simplemente usando node.js no expreso)

Mi problema es que parece que no puedo cargar un archivo css y js externo en un archivo html.

GET http://localhost:8080/css/style.css 404 (Not Found) 
GET http://localhost:8080/js/script.css 404 (Not Found) 

(esto fue cuando todos los archivos estaban en la raíz de la aplicación)

me dijeron para imitar un poco la siguiente estructura aplicación, añadir una ruta para el directorio público para permitir que el servidor web para servir a la archivos externos.

la estructura de mi aplicación es igual que

domain.com 
    app/ 
    webserver.js 

    public/ 
    chatclient.html 

    js/ 
     script.js 

    css/ 
     style.css 

Así que mi guión webserver.js está en la raíz de la aplicación, y todo lo que quiero de acceso está en 'público'.

También vi this example que usa path.extname() para obtener cualquier extensión de archivos ubicada en una ruta. (ver el último bloque de código).

Así que he intentado combinar la nueva estructura del sitio y este ejemplo path.extname(), para que el servidor web permita el acceso a cualquier archivo en mi directorio público, así puedo renderizar el archivo html, que hace referencia al js y css archivos.

Mi webserver.js tiene este aspecto.

var http = require('http') 
, url = require('url') 
, fs = require('fs') 
, path = require('path') 
, server; 

server = http.createServer(function(req,res){ 

    var myPath = url.parse(req.url).pathname; 

    switch(myPath){ 

     case '/public': 

     // get the extensions of the files inside this dir (.html, .js, .css) 
     var extname = mypath.extname(path); 

      switch (extname) { 

      // get the html 
      case '.html': 
       fs.readFile(__dirname + '/public/chatclient.html', function (err, data) { 
       if (err) return send404(res); 
       res.writeHead(200, {'Content-Type': 'text/html'}); 
       res.write(data, 'utf8'); 
       res.end(); 
       }); 
      break; 

      // get the script that /public/chatclient.html references 
      case '.js': 
       fs.readFile(__dirname + '/public/js/script.js', function (err, data) { 
       if (err) return send404(res); 
       res.writeHead(200, { 'Content-Type': 'text/javascript' }); 
       res.end(content, 'utf-8'); 
       res.end(); 
       }); 
      break; 

      // get the styles that /public/chatclient.html references 
      case '.css': 
       fs.readFile(__dirname + '/public/css/style.css', function (err, data) { 
       if (err) return send404(res); 
       res.writeHead(200, { 'Content-Type': 'text/javascript' }); 
       res.end(content, 'utf-8'); 
       res.end(); 
       }); 
      } 
      break; 

      default: send404(res); 
     } 
    }); 

Dentro de la caja de público, estoy tratando de conseguir alguna de las carpetas/archivos dentro de este directorio a través de var = extname mypath.extname (ruta); Similar al enlace que proporcioné.

Pero por el momento 'extname' está vacío cuando el registro de consola.

¿Alguien puede aconsejarme qué podría necesitar agregar o usar aquí? Soy consciente de que esto se puede hacer fácilmente en Express, pero me gustaría saber cómo lograr lo mismo simplemente confiando en Node.

Agradeceré cualquier ayuda al respecto.

Gracias de antemano.

+0

Intente imprimir el valor de 'err' antes de llamar a la función' send404() 'para ver cuál es el error real. – monsur

Respuesta

27

Existen varios problemas con su código.

  1. Su servidor no se ejecutará ya que no ha especificado un puerto desde donde escuchar.
  2. Como Eric señaló que su condición de caso fallará ya que 'public' no aparece en la url.
  3. Estás haciendo referencia a un 'contenido' variable inexistente en tus respuestas js y css, debería ser 'datos'.
  4. Su css encabezado de tipo de contenido debería ser text/css en lugar de text/javascript
  5. No es necesario especificar 'utf8' en el cuerpo.

He vuelto a escribir el código. Aviso que no uso estuche/interruptor. Prefiero mucho más simple, si no, puedes volver a colocarlos si así lo prefieres. Los módulos url y path no son necesarios en mi re-escritura, así que los eliminé.

var http = require('http'), 
    fs = require('fs'); 

http.createServer(function (req, res) { 

    if(req.url.indexOf('.html') != -1){ //req.url has the pathname, check if it conatins '.html' 

     fs.readFile(__dirname + '/public/chatclient.html', function (err, data) { 
     if (err) console.log(err); 
     res.writeHead(200, {'Content-Type': 'text/html'}); 
     res.write(data); 
     res.end(); 
     }); 

    } 

    if(req.url.indexOf('.js') != -1){ //req.url has the pathname, check if it conatins '.js' 

     fs.readFile(__dirname + '/public/js/script.js', function (err, data) { 
     if (err) console.log(err); 
     res.writeHead(200, {'Content-Type': 'text/javascript'}); 
     res.write(data); 
     res.end(); 
     }); 

    } 

    if(req.url.indexOf('.css') != -1){ //req.url has the pathname, check if it conatins '.css' 

     fs.readFile(__dirname + '/public/css/style.css', function (err, data) { 
     if (err) console.log(err); 
     res.writeHead(200, {'Content-Type': 'text/css'}); 
     res.write(data); 
     res.end(); 
     }); 

    } 

}).listen(1337, '127.0.0.1'); 
console.log('Server running at http://127.0.0.1:1337/'); 
2

public no aparece en la URL solicitada por el cliente, por lo que el cambio en myPath siempre se producirá.

7

Es posible que desee ver en el uso de marcos de servidor como express que le permiten configurar un directorio 'público' para los archivos estáticos de enrutamiento de forma automática

var express = require('express'),app = express(); 
app.use(express.static(path.join(__dirname, 'public'))); 

La sobrecarga barata de un marco de este tipo sería realmente vale la pena el esfuerzo de 'reinventar la rueda' efectivamente '

+1

Gracias, pero como dije al final, me gustaría saber cómo hacer esto con Node.js sin Express. –

+1

funciona conmigo, pero necesitaba reemplazar 'público' por '' en mi caso – z0r0

1

Podría considerar mirar el middleware Static provisto en Connect. Ver el código fuente de Static podría darle algunas ideas sobre cómo hacerlo con el código node.js (si desea aprender cómo hacerlo sin utilizar una biblioteca existente).

0
// get the extensions of the files inside this dir (.html, .js, .css) 
    var extname = **mypath**.extname(path); 

Estos están invertidos. Debe ser:

var extension = path.extname(mypath); 

Tampoco utilizo los nombres de las funciones para los nombres de las variables cuando puedo evitarlo.

0

Auto Actualizar archivos al cambiar, demora para la actualización 1 seg. Formato: app.js | index.htm | style.css

// packages 
const http = require('http'); 
const fs = require('fs'); 
// server properties 
const hostname = '127.0.0.1'; 
const port = 3000; 
const timer = 300; 

//should trigger atualize function every timer parameter 
let htmlfile = ''; 
let cssfile = ''; 
let jsfile = ''; 

uptodate(); 

// should read file from the disk for html 
function uptodate() 
{ 
    console.log(1); 
    fs.readFile('./index.html', function (err, html) { 
    if (err) { 
     throw err; 
    }  
    htmlfile = html; 
    }); 
    // should read css from the disk for css 
    fs.readFile('./style.css', function (err, html) { 
    if (err) { 
     throw err; 
    }  
    cssfile = html; 
    }); 

    // should read js file from the disk 
    fs.readFile('./app.js', function (err, html) { 
    if (err) { 
     throw err; 
    }  
    jsfile = html; 
    }); 
    setTimeout(function(){ uptodate(); }, 1000); 
} 
const server = http.createServer((req, res) => { 
    res.statusCode = 200; 

    // should send css and js 
    if(req.url.indexOf('.css') != -1){ //req.url has the pathname, check if it conatins '.js' 
    res.writeHead(200, {'Content-Type': 'text/css'}); 
    res.write(cssfile); 
    res.end(); 
    return; 
    } 
    if(req.url.indexOf('.js') != -1){ //req.url has the pathname, check if it conatins '.js' 
    res.writeHead(200, {'Content-Type': 'text/javascript'}); 
    res.write(jsfile); 
    res.end(); 
    return; 
    } 
    // should send html file via request 
    res.writeHeader(200, {"Content-Type": "text/html"}); 
    res.write(htmlfile); 
    res.end(); 
}); 

// should send css and js 

server.listen(port, hostname,() => { 
    console.log(`Server running at http://${hostname}:${port}/`); 
});