simple node.js web server with js server page
2011-2-19
一开始捣鼓node.js时我就想用它快速建一个网页,但它没有自带的像jsp asp php那样可以把脚本嵌入页面的功能,尝试用john的micro-Template做一个很简单的能在页面嵌入脚本的web server
//server.js var url = require('url'), fs = require('fs'), path = require('path'), http = require('http'), util = require('util'), querystring = require('querystring'), contentTypes = { "css" : "style/css", "flv": "video/x-flv", "gif": "image/gif", "html": "text/html", "jssp": "text/html", "jpeg": "image/jpeg", "jpg": "image/jpeg", "js": "text/javascript", "json": "application/json", "pdf": "application/pdf", "svg": "image/svg+xml", "swf": "application/x-shockwave-flash", "txt": "text/plain", }, tmpl = function (str, data){ var fn = new Function("obj", "var p=[]" + ",print=function(){p.push.apply(p,arguments);}" + ",dump=function(o){print(obj.inspect(o))};" + "with(obj){p.push('" + str .replace(/[\r\t\n]/g, " ") .split("<%").join("\t") .replace(/((^|%>)[^\t]*)'/g, "$1\r") .replace(/\t=(.*?)%>/g, "',$1,'") .split("\t").join("');") .split("%>").join("\np.push('") .split("\r").join("\\'") + "');}return p.join('');"); return data ? fn( data ) : fn; }, handler404 = function(req, res){ res.writeHead(404, {'Content-Type': 'text/plain'}); res.end('Page Not Found'); }, handler500 = function(req, res, err){ res.writeHead(500, {'Content-Type': 'text/plain'}); res.end(err); }, handler = function(req, res, dir){ //处理默认首页 var pathname = url.parse(req.url).pathname; if (pathname.substr(pathname.length-1, 1) == "/") pathname += "index.html"; filePath = path.join(__dirname, dir, pathname); path.exists(filePath, function(exists) { if(!exists) { handler404(req, res); return; } fs.readFile(filePath, "binary", function(err, file) { if(err) { handler500(req, res, err); return; } var ext = path.extname(filePath); ext = ext ? ext.slice(1) : 'html'; res.writeHead(200, {'Content-Type': contentTypes[ext], "connection" : "close"}); if (ext == 'jssp') { file = tmpl(file, { POST : req.post, GET : req.get, inspect : util.inspect }); } res.write(file, "binary"); res.end(); }); }); }, server = http.createServer(function(req, res){ var _postData = '', _getData = req.url.split("?")[1]; req.on('data', function(chunk){ _postData += chunk; }) .on('end', function(){ req.post = querystring.parse(_postData); req.get = querystring.parse(_getData); handler(req, res); }); }); server.listen(8080); console.log("Server run at 127.0.0.1:8080");
运行它,请求的文件中后缀为jssp会编译,其他的作静态文件输出。index.jssp可以这样写:
<html> <head> <title>test page</title> </head> <body> <p> post : <% dump(POST); %> </p> <p> get : <% dump(GET); %> </p> <% var fi = function(num) { return num < 2 ? 1 : fi(num - 1) + fi(num - 2); }; %> <% for (var i = 0; i < 10; i ++) { %> <p> <%= fi(i) %> </p> <% } %> <form method="POST" action="index.jssp"> <input type="text" name="name" /> <input type="password" name="pw" /> <input type="submit" value="submit" /> </form> </body> </html>
存在的问题:
1.嵌入页面的程序语法有错误会导致服务器中断,可以加上try catch解决,但catch里无法看到哪个地方出错,无法调试。
2.页面通过js编译效率会低,没有加上cache。