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:
评论

*

*

Baidu
sogou