Node(7) Routing and serving static pages

Routing usually involve in module url or querystring

A simple routing example:

var http = require('http');

//pages to be route
var pages = [
	{route: '/', output: 'Woohoo!'},
	{route: '/about/this', output: 'A simple routing with node example' },
	{route: '/another page/this', output: function(){
		return 'Here\'s '+this.route;}},
	];

http.createServer(function (request, response) {
	//get url from request
	var lookup = decodeURI( request.url );
	
	pages.forEach( function( page ){
		//find a match route
		if( page.route === lookup ){
			response.writeHead(200, {'Content-Type':'text/html'});
			response.end( typeof page.output === 'function'?
				page.output() : page.output );
		}
	});
	
	//match not found
	if( !response.finished ){
		response.writeHead(404);
		response.end( '{page Not Found!' );
	}
	
}).listen(9000);

console.log( "Server started" );


Routing to static content

var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );

var mimeTypes = {
	'.js' : 'text/javascript',
	'.html': 'text/html',
	'.css': 'text/css'
};

http.createServer( function( request, response ){
	if( request.url === '/favicon' ){
		response.end();
		return;
	}
	
	var lookup = path.basename( decodeURI( request.url ))|| 'index.html';
	
	//get file from content folder
	var file = 'content/' + lookup;
	
	//return the selected file
	fs.exists( file, function( exists ){
		if( exists ){
			fs.readFile( file, function( err, data ){
				if( err ) { response.writeHead(500 );
					response.end( 'Server Error!' ); return;
				}
				
				var headers = { 'Content-Type': mimeTypes[path.extname( lookup ) ] };
				response.writeHead( 200, headers  );
				response.end( data );
			});
		}
	});
}).listen( 9000 );

console.log( 'server started' );


routing with cache

var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );

var mimeTypes = {
	'.js' : 'text/javascript',
	'.html': 'text/html',
	'.css': 'text/css'
};

var cache = {}
function cacheAndDeliver( f, cb ){
	fs.stat( f, function( err, stats ){
		var lastChanged = Date.parse( stats.mtime );
		var isUpdated = (cache[f] ) && lastChanged > cache[f].timestamp;
		
		//no cache or updated
		if( !cache[f] || isUpdated ) {
			fs.readFile( f, function( err, data ){
				if( !err ) {
					
					cache[f] = { content : data, 
						timestamp: Date.now() 
					};
					
				}
			cb( err, data );
			});
			
		}else{
			//use cache
			console.log( 'load ' + f + ' from cache');
			cb( null, cache[f].content );
		}
		
	});
	
}

http.createServer( function( request, response ){
	if( request.url === '/favicon' ){
		response.end();
		return;
	}
	
	var lookup = path.basename( decodeURI( request.url ))|| 'index.html';
	
	//get file from content folder
	var f = 'content/' + lookup;
	
	//return the selected file
	fs.exists( f, function( exists ){
		if( exists ){
			cacheAndDeliver( f, function( err, data ){
				if( err ){
					response.WriteHead({ 'Status': 404 });
				}	
			
				response.writeHead(200,{'Content-Type' : mimeTypes[path.extname]});
				response.end( data );
			});
		};
	});
}).listen( 9000 );

console.log( 'server started' );

The above routing technique are insecure. users can use ../../ to access files not in the content folder.



secure routing;

To prevent unauthorized access to file. append '-serve' at the end of html, css, js file first, check file name before serving static pages

var http = require( 'http' );
var path = require( 'path' );
var fs = require( 'fs' );
var url = require( 'url');

var mimeTypes = {
	'.js' : 'text/javascript',
	'.html': 'text/html',
	'.css': 'text/css'
};

var cache = {}
http.createServer( function( request, response ){
	console.log( request.url );
	var lookup = url.parse( decodeURI( request.url )).pathname;
	lookup = (lookup === "/")? '/index.html_serve':lookup + '_serve';
	
	//get file from content folder
	var f = 'content-pseudosafe' + lookup;
	
	//return the selected file
	fs.exists( f, function( exists ){
		if( exists ){
			var extension = f.substring( f.lastIndexOf('.'), f.lastIndexOf('_') );
			var headers = {'Content-Type': mimeTypes[extension]};
			console.log( headers );
			if( cache[f] ){
				response.writeHead(200, headers );
				response.end( cache[f].content );
				return;
			}
		
			//createReadStream creates a ReadStream object
			var s = fs.createReadStream(f).once( 'open', function(){
				response.writeHead(200, headers );
				
				//stream the ReadStream to network socket via response
				this.pipe(response); 
			}).once('error', function(e){
				console.log(e);
				response.writeHead(500);
				response.end( 'Server Error!' );
			});
			
			fs.stat(f, function(err, stats){
				var bufferOffset = 0;
				cache[f] = { content: new Buffer(stats.size), };
				s.on( 'data', function( chunk ){
					chunk.copy(cache[f].content, bufferOffset);
					bufferOffset += chunk.length;
				});
			});
			return;
		}
		response.writeHead(404);// no such file found
		response.end( 'Page Not Found!' );
	});
}).listen( 9000 );

console.log( 'server started' );



Serving static web pages using node-static:

var static = require( 'node-static' );
var fileServer = new static.Server('./content');
require('http').createServer(function( request, response){
	request.on('end', function(){
		fileServer.serve( request, response );
	});
}).listen(9000);
node-static Reference


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值