node一些代码

node入门这个教程简单却生动有趣,涵盖了服务器端Javascript,函数式编程,阻塞与非阻塞,回调,Listener事件以及内部外部模块等许多内容。跟着这个教程把代码敲打一边,也算做了个简单的node服务器端代码框架,再要加handler就很方便了。

npm install formidable
需要安装第三方模块formidable,编写下面 四个文件

服务器入口文件 index.js

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
handle["/show"] = requestHandlers.show;

server.start(router.route, handle);

服务器文件 server.js

var http = require("http");
var url = require("url");

function start(route, handle){
	var server = http.createServer(function(request,response){
			var pathname = url.parse(request.url).pathname;
			console.log("Requesti for " + pathname + " received.");
			route(handle, pathname, response, request);
			});

	server.listen(8888);
	console.log("Server has started.");
}

exports.start = start;

路由器 router.js

//
// 路由函数
//
function route(handle, pathname, response, request){
	console.log("Route the request for " + pathname);
	if(typeof handle[pathname] === "function"){
		handle[pathname](response, request);
	} else {
		console.log("no handler set for " + pathname);
		response.writeHead(404, {"Content-Type":"text/plain"});
		response.write("404 not found");
		response.end();
	}
}

exports.route = route;

handler处理器 requestHandlers.js

var querystring = require("querystring"),
    fs = require("fs"),
    formidable = require("formidable");

var url = require("url");

//
// 显示上传表单
//
function start(response, request){
	console.log("Request Handler 'start' was called.");

	var body = '' +
		'' +
		'' +
		'' +
		'' +
		'
' + '' + '' + '
' + '' + ''; response.writeHead(200, {"Content-Type": "text/html"}); response.write(body); response.end(); } // // 使用formidable库,设置回调函数 // function upload(response, request){ console.log("Request Handler 'upload' was called."); var form = new formidable.IncomingForm(); console.log("start to parse"); form.parse(request, function(error, fields, files){ console.log("parsing done"); fs.renameSync(files.upload.path, "./test.png"); response.writeHead(200, {"Content-Type":"text/plain"}); response.write("received image:
"); response.write(""); response.end(); }); } // // 显示上传图片,通过回调函数输出 // function show(response,request){ console.log("Request Handler 'show' was called."); fs.readFile("./test.png", "binary", function(error, file){ if(error){ response.writeHead(500, {"Content-Type":"text/plain"}); response.write(error + "\n"); response.end(); } else { response.writeHead(200, {"Content-Type":"image/png"}); response.write(file, "binary"); response.end(); } }); } // // 导出handlers供router配置使用 // exports.start = start; exports.upload = upload; exports.show = show;

运行方法node index.js,可以看到实现了文件上传展示的功能。

再要实现其它功能只需要添加自定义的handler并注册到路由上即可。

再参考这篇博文介绍加上静态文件服务功能,最后代码如下

配置文件config.js(网站根目录,资源过期时间配置,压缩选项等设置)

//
// 配置过期事件的文件类型
//
exports.Expires = {
	fileMatch : /^(gif|png|jpg|js|css)$/ig,
	maxAge: 60 * 60 * 24
};

//
// 配置需要gzip压缩的文件类型
//
exports.Compress = {
	fileMatch : /^(css|js|html)$/ig
};

//
// 配置目录首页
//
exports.Welcome = {
	file: "index.html"
};

//
// 配置网站根目录
//
exports.Webroot = {
	path: "webroot"
};

mime.js自定义静态文件类型

//
// mime tyoe
//
exports.types = {
	"css": "text/css",
	"gif": "image/gif",
	"html": "text/html",
	"ico": "image/x-icon",
	"jpeg": "image/jpeg",
	"jpg": "image/jpeg",
	"js": "text/javascript",
	"json": "application/json",
	"pdf": "application/pdf",
	"png": "image/png",
	"svg": "image/svg+xml",
	"swf": "application/x-shockwave-flash",
	"tiff": "image/tiff",
	"txt": "text/plain",
	"wav": "audio/x-wav",
	"wma": "audio/x-ms-wma",
	"wmv": "video/x-ms-wmv",
	"xml": "text/xml"
};

router.js修改路由实现静态文件服务器功能

var path = require("path");
var fs = require("fs");
var mime = require("./mime").types;
var config = require("./config");
var zlib = require("zlib");
//
// router
//
function route(handle, pathname, response, request){
	console.log("Route the request for " + pathname);

	var realpath = config.Webroot.path + pathname;
	
	fs.stat(realpath, function(err, stat){
			//
			// Handlers
			//
			if(err)
			{
				if(typeof handle[pathname] === "function"){
					handle[pathname](response, request);
				}
				// file not exists
				else {
					response.writeHead(404, {"Content-Type":"text/plain"});
					response.write("404 not found");
					response.end();
				}
				return;
			}
			//
			// change /dir to /dir/index.html
			//
			if(stat.isDirectory()) {
				realpath = path.join(realpath, "/", config.Welcome.file);
			}
			//
			// exists Files
			//
			fs.exists(realpath, function(exists){
				if(!exists) {
					response.writeHead(404, {"Content-Type":"text/plain"});
					response.write("404 not found");
					response.end();
					return;
				}
			
				//
				// set last-modified
				//
				var lastModified = stat.mtime.toUTCString();
				response.setHeader("Last-Modified", lastModified);

				if(request.headers["if-modified-since"] && lastModified == request.headers["if-modified-since"]) {
				response.writeHead(304, "Not Modified");	
				response.end();
				return;
				}

				var ext = path.extname(realpath);
				ext = ext ? ext.slice(1) : 'unknown';

				//
				// set content-type
				//
				var contentType = mime[ext] || "text/plain";
				response.setHeader("Content-Type", contentType);

				//
				// set expire time
				//
				if(ext.match(config.Expires.fileMatch)) {
					var expires = new Date();
					expires.setTime(expires.getTime() +
							config.Expires.maxAge * 1000);
					response.setHeader("Expires", 
							expires.toUTCString());
					response.setHeader("Cach-Control", 
							"max-age=" + config.Expires.maxAge);
				}

				var raw = fs.createReadStream(realpath);
				var acceptEncoding = request.headers['accept-encoding'] || "";
				var match = ext.match(config.Compress.fileMatch);
				//
				// compress and echo
				//
				if(match && acceptEncoding.match(/\bgzip\b/)){
					response.writeHead(200,
							{"Content-Encoding":"gzip"}
							);
					raw.pipe(zlib.createGzip()).pipe(response);
				} else if(match && acceptEncoding.match(/\bdeflate\b/)){
					response.writeHead(200,
							{"Content-Encoding":"deflate"}
							);
					raw.pipe(zlib.createDeflate()).pipe(response);
				} else {
					response.writeHead(200, "Ok");
					raw.pipe(response);
				}
			});
	});
}

exports.route = route;

经过上面的修改,不但能自定义handle处理请求,也能支持静态文件(html,css,图片等),其中静态文件全部放在webroot目录下。当然最好还是使用现成的express框架。

你可能感兴趣的:(Server)