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。

分类:技术文章 Tags:
评论

*

*