Usando Node.js como un servidor web simple
Quiero ejecutar un servidor HTTP muy simple. Cada solicitud GET example.com
debe index.html
entregarse, pero como una página HTML normal (es decir, la misma experiencia que cuando lees páginas web normales).
Usando el siguiente código, puedo leer el contenido de index.html
. ¿ Cómo sirvo index.html
como una página web normal?
var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(index);
}).listen(9615);
Una de las sugerencias a continuación es complicada y requiere que escriba una get
línea para cada archivo de recursos (CSS, JavaScript, imágenes) que quiero usar.
¿Cómo puedo servir una sola página HTML con algunas imágenes, CSS y JavaScript?
El servidor Node.js más simple es simplemente:
$ npm install http-server -g
Ahora puede ejecutar un servidor mediante los siguientes comandos:
$ cd MyApp
$ http-server
Si está utilizando NPM 5.2.0 o posterior, puede usarlo http-server
sin instalarlo con npx
. No se recomienda su uso en producción, pero es una excelente manera de ejecutar rápidamente un servidor en localhost.
$ npx http-server
Para evitar problemas de seguridad y experiencia del usuario al escribir mal los nombres de los paquetes, npx avisa antes de instalar cualquier cosa. Puede suprimir este mensaje con la opción -y o --yes:
$ npx -y http-server
O puede probar esto, que abre su navegador web y habilita las solicitudes CORS:
$ http-server -o --cors
Para obtener más opciones, consulte la documentación http-server
en GitHub o ejecute:
$ http-server --help
Muchas otras características interesantes y una implementación increíblemente simple en NodeJitsu.
Característica Horquillas
Por supuesto, puedes recargar fácilmente las funciones con tu propio fork. Es posible que descubras que ya se ha realizado en una de las más de 800 bifurcaciones existentes de este proyecto:
- https://github.com/nodeapps/http-server/network
Servidor ligero: una alternativa de actualización automática
Una buena alternativa http-server
es light-server
. Admite la visualización de archivos y la actualización automática y muchas otras funciones.
$ npm install -g light-server
$ light-server
Agregue al menú contextual de su directorio en el Explorador de Windows
reg.exe add HKCR\Directory\shell\LightServer\command /ve /t REG_EXPAND_SZ /f /d "\"C:\nodejs\light-server.cmd\" \"-o\" \"-s\" \"%V\""
Servidor REST JSON simple
Si necesita crear un servidor REST simple para un proyecto prototipo, entonces json-server podría ser lo que está buscando.
Editores de actualización automática
La mayoría de los editores de páginas web y herramientas IDE ahora incluyen un servidor web que observará sus archivos fuente y actualizará automáticamente su página web cuando cambien.
Utilizo Live Server con Visual Studio Code.
El editor de texto de código abierto Brackets también incluye un servidor web estático NodeJS. Simplemente abra cualquier archivo HTML entre corchetes, presione " Vista previa en vivo " e iniciará un servidor estático y abrirá su navegador en la página. El navegador se actualizará automáticamente cada vez que edite y guarde el archivo HTML. Esto es especialmente útil al probar sitios web adaptables. Abra su página HTML en múltiples navegadores/tamaños de ventana/dispositivos. Guarde su página HTML y vea instantáneamente si sus elementos adaptativos funcionan, ya que todos se actualizan automáticamente.
Web / SPA / PWA / Móvil / Escritorio / Navegador Ext Web Developers
Algunos marcos de SPA incluyen una versión integrada de Webpack DevServer que puede detectar cambios en el archivo fuente y desencadenar una reconstrucción incremental y un parche (llamado recarga en caliente) de su aplicación web SPA o PWA. A continuación se muestran algunos marcos SPA populares que pueden hacer esto.
Desarrolladores de VueJS
Para los desarrolladores de VueJS, uno de los favoritos es Quasar Framework , que incluye Webpack DevServer listo para usar con modificadores para admitir la representación del lado del servidor (SSR) y reglas de proxy para solucionar sus problemas de CORS. Incluye una gran cantidad de componentes optimizados diseñados para adaptarse tanto para dispositivos móviles como para computadoras de escritorio. Esto le permite crear una aplicación para TODAS las plataformas (aplicaciones SPA, SPA+SSR, PWA, PWA+SSR, Cordova y Capacitor Mobile AppStore, aplicaciones Electron Desktop Node+VueJS e incluso extensiones de navegador).
Otro popular es NuxtJS , que también admite la generación de código HTML/CSS estático, así como modos de compilación SSR o no SSR con complementos para otros conjuntos de componentes de UI.
Desarrolladores de marcos de reacción
Los desarrolladores de ReactJS también pueden configurar la recarga en caliente .
Desarrolladores de Cordova/Capacitor + Ionic Framework
Iconic es un marco de componentes híbridos solo para dispositivos móviles que ahora admite el desarrollo de VueJS, React y Angular. La herramienta incluye un servidor local con funciones de actualización automática ionic
. Simplemente ejecútelo ionic serve
desde la carpeta de su aplicación. Aún mejor... ionic serve --lab
para ver vistas de actualización automática una al lado de la otra de iOS y Android.
Nota : Esta respuesta es de 2011. Sin embargo, sigue siendo válida.
Puedes usar Connect y ServeStatic con Node.js para esto:
Instale connect y server-static con NPM
$ npm install connect serve-static
Cree el archivo server.js con este contenido:
var connect = require('connect'); var serveStatic = require('serve-static'); connect() .use(serveStatic(__dirname)) .listen(8080, () => console.log('Server running on 8080...'));
Ejecutar con Node.js
$ node server.js
Ahora puedes ir ahttp://localhost:8080/yourfile.html
Mira esta esencia . Lo reproduzco aquí como referencia, pero la esencia se ha actualizado periódicamente.
Servidor web de archivos estáticos Node.JS. Colóquelo en su ruta para activar servidores en cualquier directorio, toma un argumento de puerto opcional.
var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs"),
port = process.argv[2] || 8888;
http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname
, filename = path.join(process.cwd(), uri);
fs.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
return;
}
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
return;
}
response.writeHead(200);
response.write(file, "binary");
response.end();
});
});
}).listen(parseInt(port, 10));
console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown");
Actualizar
La esencia maneja archivos css y js. Lo he usado yo mismo. Usar lectura/escritura en modo "binario" no es un problema. Eso simplemente significa que la biblioteca de archivos no interpreta el archivo como texto y no está relacionado con el tipo de contenido devuelto en la respuesta.
El problema con su código es que siempre devuelve un tipo de contenido de "texto/sin formato". El código anterior no devuelve ningún tipo de contenido, pero si solo lo usa para HTML, CSS y JS, un navegador puede inferirlos sin problemas. Ningún tipo de contenido es mejor que uno incorrecto.
Normalmente el tipo de contenido es una configuración de su servidor web. Lo siento si esto no resuelve su problema, pero funcionó para mí como un servidor de desarrollo simple y pensé que podría ayudar a otras personas. Si necesita tipos de contenido correctos en la respuesta, debe definirlos explícitamente como lo hace joeytwiddle o usar una biblioteca como Connect que tenga valores predeterminados sensatos. Lo bueno de esto es que es simple y autónomo (sin dependencias).
Pero siento tu problema. Así que aquí está la solución combinada.
var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs")
port = process.argv[2] || 8888;
http.createServer(function(request, response) {
var uri = url.parse(request.url).pathname
, filename = path.join(process.cwd(), uri);
var contentTypesByExtension = {
'.html': "text/html",
'.css': "text/css",
'.js': "text/javascript"
};
fs.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not Found\n");
response.end();
return;
}
if (fs.statSync(filename).isDirectory()) filename += '/index.html';
fs.readFile(filename, "binary", function(err, file) {
if(err) {
response.writeHead(500, {"Content-Type": "text/plain"});
response.write(err + "\n");
response.end();
return;
}
var headers = {};
var contentType = contentTypesByExtension[path.extname(filename)];
if (contentType) headers["Content-Type"] = contentType;
response.writeHead(200, headers);
response.write(file, "binary");
response.end();
});
});
}).listen(parseInt(port, 10));
console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown");
No necesitas expreso. No necesitas conectarte. Node.js hace http DE FORMA NATIVA. Todo lo que necesita hacer es devolver un archivo dependiendo de la solicitud:
var http = require('http')
var url = require('url')
var fs = require('fs')
http.createServer(function (request, response) {
var requestUrl = url.parse(request.url)
response.writeHead(200)
fs.createReadStream(requestUrl.pathname).pipe(response) // do NOT use fs's sync methods ANYWHERE on production (e.g readFileSync)
}).listen(9615)
Un ejemplo más completo que garantiza que las solicitudes no puedan acceder a los archivos debajo de un directorio base y realiza un manejo adecuado de los errores:
var http = require('http')
var url = require('url')
var fs = require('fs')
var path = require('path')
var baseDirectory = __dirname // or whatever base directory you want
var port = 9615
http.createServer(function (request, response) {
try {
var requestUrl = url.parse(request.url)
// need to use path.normalize so people can't access directories underneath baseDirectory
var fsPath = baseDirectory+path.normalize(requestUrl.pathname)
var fileStream = fs.createReadStream(fsPath)
fileStream.pipe(response)
fileStream.on('open', function() {
response.writeHead(200)
})
fileStream.on('error',function(e) {
response.writeHead(404) // assume the file doesn't exist
response.end()
})
} catch(e) {
response.writeHead(500)
response.end() // end the response so browsers don't hang
console.log(e.stack)
}
}).listen(port)
console.log("listening on port "+port)