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。