Nodejs实现简易HTTP服务器

很早以前没事干搞的,来体验一下Nodejs的回调地狱

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

const formidable = require('formidable');
const sd = require("silly-datetime");


const server = http.createServer((request,response)=>{
	const pathname = url.parse(request.url).pathname;
	const query = url.parse(request.url,true).query; //这里加true 就和querystring.parse的效果一样了
	//search 是get请求包含?的信息 比如会返回  ?a=b
	//query 是 get请求的信息,和search的区别是 search 是包含了?和& 但是上面的代码我加了true 等于他会解析成类似dictionary的内容
	//path url 除了域名端口所有信息
	//href 目前没发现和path有什么区别
	//console.log(pathname,query)
	
	
	

	
	//下面详细区分mime
	var resType = "application/octet-stream;"; //默认的
	
	const extension = path.extname(pathname); //获取扩展文件名
	// 就写这么多 有兴趣可以从任意一个web容器mime里拷出来
	const mimeType = {
		".html":"text/html;charset=utf-8;", 
		".htm":"text/html;charset=utf-8;",
		".jpg":"image/jpeg;",
		".jpeg":"image/jpeg;",
		".png":"image/png;",
		".gif":"image/gif;",
		".ico":"image/vnd.microsoft.icon;",
		".txt":"text/plain;charset=utf-8;",
		".json":"application/json;",
		".mp4":"video/mp4;",
		".ogg":"video/ogg;",
		".js":"application/x-javascript;charset=utf-8;",
		".mjs":"application/x-javascript;charset=utf-8;",
		".css":"text/css;charset=utf-8;"
	};
	
	if (Object.keys(mimeType).indexOf(extension)>-1){
		resType = mimeType[extension];
	}
	
	console.log(pathname+"   "+request.url+"  "+request.method);
	
	if (pathname=='/'){
		fs.readFile("./result.html",function(err,data){
			if (err){
				response.writeHead(404,{"Content-type": "text/html;charset=utf-8;"});
				response.end('<h1>404 Not Found</h1>');
				return false;
			}
            response.writeHead(200, {'content-type': 'text/html;charset=utf-8;'});
            response.end(data);
        })
	}else if(pathname=='/favicon.ico'){
		response.writeHead(200,{"Content-type": resType});
		fs.readFile("./favicon.ico",(err,data)=>{
			if (err){
				response.end();
				return false;
			}
			response.write(data);
			response.end();
			
		});
		
	}else if(pathname == "/upload" && request.method == "POST"){
		
		var form = new formidable.IncomingForm();
        //设置文件上传存放地址
        form.uploadDir = "./uploads";
        //执行里面的回调函数的时候,表单已经全部接收完毕了。
        form.parse(request, function(err, fields, files) {
			//console.log(fields)
            var fileTime = sd.format(new Date(), 'YYYYMMDDHHmmss');
            var ran = parseInt(Math.random() * 89999 + 10000);
            var extname = path.extname(files.upload.name);
            //执行改名
            var oldpath = __dirname + "/" + files.upload.path;
            //新的路径由三个部分组成:时间戳、随机数、拓展名
            var newpath = __dirname + "/uploads/" + fileTime + ran + extname;

            //改名
            fs.rename(oldpath,newpath,function(err){
                if(err){
                    throw Error("改名失败");
                }
                response.writeHead(200, {'content-type': 'text/plain'});
                response.end("成功");
            });
        });
		
	}else{
		// 扩展名限制
		if (extension && Object.keys(mimeType).indexOf(extension)<0){
			response.writeHead(403,{"Content-type": "text/html;charset=utf-8;"});
			response.end(`<h1>禁止访问 ${extension} 扩展名文件</h1>`);
			return false;
		}	
		
		fs.stat(path.join(__dirname,pathname),(err,stats)=>{
			if (err){
				response.writeHead(404,{"Content-type": "text/html;charset=utf-8;"});
				response.end('<h1>404 Not Found</h1>');
				return false;
			}
			fs.readFile(path.join(__dirname,pathname),(err,data)=>{
				if (err){
					response.writeHead(403,{"Content-type": "text/html;charset=utf-8;"});
					response.end('<h1>403 Forbidden</h1>');
					return false;
				}
				/* 这样是优先判断文件是否存在,存在且访问不存在扩展名才会触发,可能会造成人家用来判断文件是否存在的特征
				if (Object.keys(mimeType).indexOf(extension)<0){
					response.writeHead(403,{"Content-type": "text/html;charset=utf-8;"});
					response.end(`<h1>禁止访问 ${extension} 扩展名文件</h1>`);
					return false;
				}	
				*/
				response.writeHead(200,{"Content-type": resType});
				response.write(data);
				response.end();
				
			});
			
		});
		
	}
});

server.listen(2080,(error)=>{
	if (error) throw error;
	console.log('成功启动web服务,端口:2080');
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没事干写博客玩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值