简单的nodejs资源服务,支持下载文件以及展示目录
/*
使用方法:
node res_server.js 资源根目录 端口
*/
let http = require("http");
let url = require("url");
let fs = require("fs");
let path = require('path');
var os = require('os');
const TextParam = {'Content-Type':'text/html;charset=utf8', "Access-Control-Allow-Origin":'*'};
const MultipartParam = {'Content-Type':"multipart/form-data", "Access-Control-Allow-Origin":'*'};
class ResServer {
constructor(params) {
this.ip = params.ip || this.getLocalIPAddress();
this.port = params.port;
this.rootPath = params.rootDir;
this.server = null;
}
start(){
this.server = http.createServer((req, res)=>{
this.onMessage(req, res);
});
console.log('ResServer: start ', "http://" + (this.ip||"localhost") + ":" + this.port);
this.server.listen(this.port);
}
close(){
this.server.close(function(){
console.log("ResServer : closed ");
});
}
onMessage(req, res){
let req_path = url.parse(req.url).path;
console.log('\n\nonMessage:', req_path);
// 解析参数
let idx = req_path.indexOf("?");
let beforePath = idx > 0 ? req_path.substr(0, idx) : req_path;
let afterParams = idx > 0 ? req_path.substr(idx) : "";
let filepath = this.getFilePath(beforePath);
// 响应
this.doResponse(filepath,res,afterParams);
}
getFilePath(req_path){
return path.join(this.rootPath,req_path);
}
sendServerError(res){
res.writeHead(500, TextParam);
res.end('<div styel="color:black;font-size:22px;"> 啊呀~服务出现异常!</div>');
}
send404NotFound(res){
res.writeHead(404, TextParam);
res.end('<div styel="color:black;font-size:22px;"> 啊呀~资源好像丢失了!</div>');
}
senfFileStream(res,filepath,reqParams){
let file = fs.createReadStream(filepath);
res.writeHead(200, reqParams.indexOf("log=1")>=0 ? TextParam : MultipartParam);
file.pipe(res);
}
sendDirListInfo(res,filepath){
let dir = filepath.replace(this.rootPath,"");
let str = '';
if(dir.length > 0){
str = "<a href=" + path.join(dir,'../') + ">..</a><br><br>";
}
fs.readdir(filepath, function(err, results){
let dirStr = '';
let fileStr = '';
results.forEach((file)=>{
if(file.startsWith(".")){return}
let stat = fs.statSync(path.join(filepath,file));
let content = "<a href=" + path.join(dir,file) + ">" + file + "</a><br><br>";
if(stat.isFile()){
fileStr += content;
}else{
dirStr += content;
}
});
res.writeHead(200, TextParam);
res.write(str + dirStr + fileStr);
res.end();
});
}
doResponse(filepath,res,reqParams){
console.log('filePath:', filepath);
fs.access(filepath,(error)=>{
if(!error){
fs.stat(filepath,(err, stats)=>{
if(err){
this.sendServerError(res);
}else{
if(stats.isFile()){// 返回文件信息
this.senfFileStream(res,filepath,reqParams);
}else{// 输出目录结构信息
this.sendDirListInfo(res,filepath);
}
}
});
}else{// 404了
this.send404NotFound(res);
}
});
}
// 获取内网ip
getLocalIPAddress() {
let ip = '';
let interfaces = os.networkInterfaces();
for (let devName in interfaces) {
let iface = interfaces[devName];
for (let i = 0; i < iface.length; i++) {
let alias = iface[i];
// 根据自己的网络环境,替换 "172.16."
if (alias.family === 'IPv4' && alias.address.startsWith("172.16.") && !alias.internal) {
ip = alias.address;
}
}
}
return ip;
}
}
let rootDir = process.argv[2] || "_error_";
if(rootDir === "_error_"){
console.error(" argv[2] : rootDir invalid !");
}else{
let port = process.argv[3] || "8888";
let ip = process.argv[4] || undefined;
let resServer = new ResServer({ ip : ip, port : port , rootDir : rootDir });
resServer.start();
}