从零开始,在windows上用nodejs搭建一个静态文件服务器

首先安装nodejs:

  • 新建一个node文件夹
  • 下载node.exe到该文件夹
  • 下载npm然后解压到该文件夹
  • 现在node文件夹是这样的
  • 把该目录加入到path环境变量
  • 在命令行执行
    node -v
    
    npm -v
    

    如果得到了版本号则表示nodejs安装完成

  • 在命令行中执行
    npm config set registry https://registry.npm.taobao.org
    

    以后安装nodejs模块 都会从淘宝的npm镜像中下载

  • 如果想要发布自己的模块到npm要先把npm的registry切换回来
    npm config set registry https://registry.npmjs.org
    

接下来搭建静态文件服务器

  • 创建一个文件夹server,一个文件夹root,server内是服务器的js代码,root是根目录
  • server文件夹里面创建js文件 index.js mime.js server.js
  • index.js
    var server = require('./server.js');
    var cp = require('child_process');
    var rootpath = 'root';
    var sv = server.create({
    port: '9587',
    host: '127.0.0.1',
    root: rootpath
    });
    cp.exec('explorer http://127.0.0.1:9587', function () {
    });

      

  • mime.js
    var types = {
    "css": "text/css",
    "less": "text/css",
    "gif": "image/gif",
    "html": "text/html",
    "ejs": "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",
    "default": "text/plain"
    };
    module.exports = function (ext) {
    return types[ext] || 'text/plain'
    }
  • server.js
    var http = require('http');
    var path = require('path');
    var fs = require('fs');
    var url = require("url");
    var mime = require('./mime.js'); function getPromise(cbk) {
    return (new Promise(cbk));
    }
    exports.create = function (opts) {
    var root = opts.root;
    var sv = http.createServer(); function request(request, response) {
    var pathname = decodeURIComponent(url.parse(request.url).pathname);
    var realPath = path.resolve(path.join(root, pathname));//请求的实际路径
    getPromise(function (resolve, reject) {
    fs.exists(realPath, function (isExists) {//判断路径是否存在
    isExists ? resolve() : reject();
    });
    }).catch(function () {
    resWrite(response, '404', 'html', '<h1>404</h1>file or dir : <h3>' + pathname + '</h3>not found');
    }).then(function () {
    return getPromise(function (resolve, reject) {
    fs.stat(realPath, function (err, stat) {//判断路径是文件还是文件夹
    if (err) {
    reject(err);
    } else {
    resolve(stat);
    }
    })
    }).then(function (stat) {
    if (stat.isFile()) {//路径对应的是一个文件
    resFile(response, realPath);
    } else if (stat.isDirectory()) {//路径对应的是一个文件夹
    var defaultIndexPath = path.resolve(realPath, 'index.html');
    return getPromise(function (resolve, reject) {
    fs.exists(defaultIndexPath, function (isExists) {
    if (isExists) {//如果该文件夹内有index.html
    resolve(true);
    } else {//该文件夹内没有index.html 则 显示该文件夹的内容列表
    resolve(false);
    }
    })
    }).then(function (isExistsIndex) {
    if (isExistsIndex) {
    resFile(response, defaultIndexPath);
    } else {
    return getPromise(function (resolve, reject) {
    fs.readdir(realPath, function (err, list) {
    if (err) {
    reject(err);
    } else {
    resolve(list);
    }
    })
    }).then(function (list) {
    var pmlist = list.map(function (item) {
    return (new Promise(function (resolve, reject) {
    fs.stat(path.resolve(realPath, item), function (err, stat) {
    if (err) {
    console.error(err);
    resolve('');
    } else if (stat.isFile()) {
    resolve(`<li class="file"><a href="${item}">${item}</a></li>`);
    } else if (stat.isDirectory()) {
    resolve(`<li class="dir"><a href="${item}/">${item}</a></li>`);
    } else {
    resolve('');
    }
    })
    }));
    });
    Promise.all(pmlist).then(function (linkList) {
    var links = '<ul>';
    links += '<li class="dir"><a href="../">../</a></li>';
    links += linkList.join('');
    links += '</ul>';
    var dirPage = `
    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8"/>
    <style>
    a{color:blue;text-decoration: none;}
    .dir a{color:orange}
    </style>
    </head>
    <body>
    ${links}
    </body>
    </html>
    `;
    resWrite(response, '200', 'html', dirPage);
    });
    }).catch(function (err) {
    resWrite(response, '500', 'default', err.toString());
    })
    }
    })
    } else {//既不是文件也不是文件夹
    resWrite(response, '404', 'html', '<h1>404</h1>file or dir : <h3>' + pathname + '</h3>not found');
    }
    }).catch(function (err) {
    resWrite(response, '500', 'default', err.toString());
    })
    })
    } sv.on('request', request);
    sv.listen(opts.port, opts.host);
    return sv;
    }; function resFile(response, realPath) {//输出一个文件
    fs.readFile(realPath, function (err, data) {
    if (err) {
    resWrite(response, '500', 'default', err.toString());
    } else {
    var ext = path.extname(realPath).toLocaleLowerCase();
    ext = (ext ? ext.slice(1) : 'unknown');
    resWrite(response, '200', ext, data);
    }
    });
    } function resWrite(response, statusCode, mimeKey, data) {
    response.writeHead(statusCode, {'Content-Type': mime(mimeKey)});
    response.end(data);
    }
  • 在server文件夹内按住shift按钮,鼠标右键点击文件夹内空白区域,点击在此处打开命令窗口,执行命令
    node index.js
    

从零开始,在windows上用nodejs搭建一个静态文件服务器的更多相关文章

  1. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(三)-使用Travis自动部署Hexo(1)

    前言 前面两篇文章介绍了在github上使用hexo搭建博客的基本环境和hexo相关参数设置等. 基于目前,博客基本上是可以完美运行了. 但是,有一点是不太好,就是源码同步问题,如果在不同的电脑上写文 ...

  2. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置

    前言 有朋友问了我关于博客系统搭建相关的问题,由于是做开发相关的工作,我给他推荐的是使用github的gh-pages服务搭建个人博客. 推荐理由: 免费:github提供gh-pages服务是免费的 ...

  3. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(四)-使用Travis自动部署Hexo(2)

    前言 前面一篇文章介绍了Travis自动部署Hexo的常规使用教程,也是个人比较推荐的方法. 前文最后也提到了在Windows系统中可能会有一些小问题,为了在Windows系统中也可以实现使用Trav ...

  4. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(二)-Hexo参数设置

    前言 前文手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置介绍了github注册.git相关设置以及hexo基本操作. 本文主要介绍一下hexo的常用参数设置. ...

  5. 用nodejs搭建一个简单的服务器

    使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安 ...

  6. windows上使用mkdocs搭建静态博客

    windows上使用mkdocs搭建静态博客 之前尝试过用HEXO搭建静态博客,最近发现有个叫mkdocs的开源项目也是搭建静态博客的好选择,而且它支持markdown格式,下面简要介绍一下mkdoc ...

  7. 利用 nodeJS 搭建一个简单的Web服务器(转)

    下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...

  8. 利用git+hugo+markdown 搭建一个静态网站

    利用git+hugo+markdown 搭建一个静态网站 一直想要有一个自己的文档管理系统: 可以很方便书写,而且相应的文档很容易被分享 很方便的存储.管理.历史记录 比较方面的浏览和查询 第一点用M ...

  9. 用nodejs搭建一个简单的服务监听程序

    作为一个从业三年左右的,并且从事过半年左右PHP开发工作的前端,对于后台,尤其是对以js语言进行开发的nodejs,那是比较有兴趣的,虽然本身并没有接触过相关的工作,只是自己私下做的一下小实验,但是还 ...

随机推荐

  1. vim操作命令-笔记

    显示行号:在vim命令行模式下输入 :set nu 或 :set number 取消显示行号:在vim命令行模式下输入 :set nonu 或 :set nonumber 查看文件编码格式: :set ...

  2. ETL控件学习之一从数据库导出数据到平面

    今天主要进行ETL控件的学习.主要是使用微软的SSDT工具.使用DataFlowTask 将数据源导出到目标文件的方式. 1.打开SSDT新建一个SSIS的project,如下图所示: 2.在SSIS ...

  3. 8个经典的HTML5游戏在线试玩及源码学习

    原文地址:http://www.oschina.net/news/32364/html5-games 游戏,毫无疑问是拿来供大家娱乐玩耍的,这也无可厚非,但是,今天给大家分享的8个HTML5游戏,在好 ...

  4. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  5. OTP语音芯片和掩模语音芯片(mask)的区别

    OTP(One Time Programable)是MCU的一种存储器类型,意思是一次性可编程:程序烧入IC后,将不可再次更改和:因此OTP语音芯片就是指一次性烧录的语音IC. 从OTP定义上来看,只 ...

  6. linux系统开机过程描述

    本文描述linux系统开机过程,属于个人理解范畴,如果文中表述有误请大家批评指正! 计算机开机之后,首先要加载BIOS(基本输入输出系统)信息,BIOS包含了很多重要的信息,包括CPU信息,设备启动顺 ...

  7. InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!

    InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的. InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoD ...

  8. weblogic jsp 不生效解决方法

    1. 检查weblogic.xml配置文件,其中如果有: <jsp-descriptor> <jsp-param> <param-name>pageCheckSec ...

  9. POJ 2112 Optimal Milking(Floyd+多重匹配+二分枚举)

    题意:有K台挤奶机,C头奶牛,每个挤奶机每天只能为M头奶牛服务,下面给的K+C的矩阵,是形容相互之间的距离,求出来走最远的那头奶牛要走多远   输入数据: 第一行三个数 K, C, M  接下来是   ...

  10. 【转】Android实例剖析笔记(二)--用实例讲解Andriod的开发过程,以NotesList为实例介绍Android的菜单机制

    原文网址:http://kb.cnblogs.com/page/78304/ 简介 android提供了三种菜单类型,分别为options menu,context menu,sub menu. op ...