写一个 nodejs npm应用 - webhere
前言、没图不说话,先上图。

What's webhere?
有没有遇到这样的场景:写程序的时候,需要访问一个文件,这个文件 需要是放到一台web服务器上,但是你不是开发的web应用。
所以呢,你不得不去找一个web服务器,把你的文件上传上去,或者干脆直接创建一个web应用程序...
webhere就是来解决这个问题,在你想要当做web根目录的目录下,打开你亲爱的命令行,敲下webhere,回车,搞定。
然后就可以通过web浏览器访问目录下的文件了。
安装:$ npm install webhere -g
运行:$ webhere
一、 原理
原理比较简单,一句话来说,就是搭建一个web服务器。
1.用nodejs的http包创建一个web服务。
2.对访问路径路由到具体的文件路径。
3.根据文件是否存在写具体的响应码,根据文件的后缀写具体Content-type。
4.返回文件的内容,响应结束。
二、 实现
1.创建nodejs的pakage.json,添加应用的bin的信息和其他描述信息。
{
"name": "webhere",
"version": "0.0.7",
"description": "Create a web server in the current directory.",
"repository": {
"type": "git",
"url": "git@github.com:smallyard/webhere.git"
},
"author": "liuhongqiang <liuhongqiang@live.cn>",
"license": "MIT",
"bin": {
"webhere": "./bin/webhere"
},
"keywords": [
"webhere",
"server",
"web server"
],
"engines": {
"node": ">= 0.10"
},
"readmeFilename": "README.md"
}
2.bin文件,程序的入口。
#!/usr/bin/env node
var server = require("../src/server");
server.start();
3.web服务,server.js
var http = require("http");
var router = require("./router");
var render = require("./render");
function start() {
function onRequest(request, response) {
var routeResult = router.route(request.url);
var responseInfo = render.getResponseInfo(routeResult);
response.writeHead(responseInfo.status, {"Content-Type": responseInfo.contentType});
response.write(responseInfo.content);
response.end();
}
http.createServer(onRequest).listen(9000);
console.log("Server has started.");
console.log("Server address: http://127.0.0.1:9000");
}
exports.start = start;
4.路由router.js
var fs = require("fs");
function route(path) {
console.log("Origin path: " + path);
if (path == "/") {
return "htmlIndex";
} else {
path = "." + path;
if (fs.existsSync(path) && fs.statSync(path).isFile()) {
return path;
} else {
return "html404";
}
}
}
exports.route = route;
5.内容渲染,render.js
var fs = require("fs");
var contentTypes = require("./contentTypes");
var HTML_INDEX = require("./html/index").html;
var HTML_404 = require("./html/404").html;
function getResponseInfo(routeResult) {
console.log("Result path: " + routeResult);
var status = 200;
var content = "";
var contentType = "text/html";
if (routeResult == "htmlIndex") {
content = HTML_INDEX;
} else if (routeResult == "html404") {
status = 404;
content = HTML_404;
} else {
content = fs.readFileSync(routeResult);
contentType = getContentType(routeResult);
}
return {
"status": status,
"contentType": contentType,
"content": content
};
}
function getContentType(filePath) {
var suffix = "";
var pointIndex = filePath.lastIndexOf(".");
if (pointIndex != -1) {
suffix = filePath.substr(pointIndex);
}
if (contentTypes.hasOwnProperty(suffix)) {
return contentTypes[suffix];
} else {
return contentTypes[".*"];
}
}
exports.getResponseInfo = getResponseInfo;
最后,附上我从开源中国上抓取的content-type
{
".*": "application/octet-stream",
".tif": "application/x-tif",
".001": "application/x-001",
".301": "application/x-301",
".323": "text/h323",
".906": "application/x-906",
".907": "drawing/907",
".a11": "application/x-a11",
".acp": "audio/x-mei-aac",
".ai": "application/postscript",
".aif": "audio/aiff",
".aifc": "audio/aiff",
".aiff": "audio/aiff",
".anv": "application/x-anv",
".asa": "text/asa",
".asf": "video/x-ms-asf",
".asp": "text/asp",
".asx": "video/x-ms-asf",
".au": "audio/basic",
".avi": "video/avi",
".awf": "application/vnd.adobe.workflow",
".biz": "text/xml",
".bmp": "application/x-bmp",
".bot": "application/x-bot",
".c4t": "application/x-c4t",
".c90": "application/x-c90",
".cal": "application/x-cals",
".cat": "application/vnd.ms-pki.seccat",
".cdf": "application/x-netcdf",
".cdr": "application/x-cdr",
".cel": "application/x-cel",
".cer": "application/x-x509-ca-cert",
".cg4": "application/x-g4",
".cgm": "application/x-cgm",
".cit": "application/x-cit",
".class": "java/*",
".cml": "text/xml",
".cmp": "application/x-cmp",
".cmx": "application/x-cmx",
".cot": "application/x-cot",
".crl": "application/pkix-crl",
".crt": "application/x-x509-ca-cert",
".csi": "application/x-csi",
".css": "text/css",
".cut": "application/x-cut",
".dbf": "application/x-dbf",
".dbm": "application/x-dbm",
".dbx": "application/x-dbx",
".dcd": "text/xml",
".dcx": "application/x-dcx",
".der": "application/x-x509-ca-cert",
".dgn": "application/x-dgn",
".dib": "application/x-dib",
".dll": "application/x-msdownload",
".doc": "application/msword",
".dot": "application/msword",
".drw": "application/x-drw",
".dtd": "text/xml",
".dwf": "application/x-dwf",
".dwg": "application/x-dwg",
".dxb": "application/x-dxb",
".dxf": "application/x-dxf",
".edn": "application/vnd.adobe.edn",
".emf": "application/x-emf",
".eml": "message/rfc822",
".ent": "text/xml",
".epi": "application/x-epi",
".eps": "application/postscript",
".etd": "application/x-ebx",
".exe": "application/x-msdownload",
".fax": "image/fax",
".fdf": "application/vnd.fdf",
".fif": "application/fractals",
".fo": "text/xml",
".frm": "application/x-frm",
".g4": "application/x-g4",
".gbr": "application/x-gbr",
".": "application/x-",
".gif": "image/gif",
".gl2": "application/x-gl2",
".gp4": "application/x-gp4",
".hgl": "application/x-hgl",
".hmr": "application/x-hmr",
".hpg": "application/x-hpgl",
".hpl": "application/x-hpl",
".hqx": "application/mac-binhex40",
".hrf": "application/x-hrf",
".hta": "application/hta",
".htc": "text/x-component",
".htm": "text/html",
".html": "text/html",
".htt": "text/webviewhtml",
".htx": "text/html",
".icb": "application/x-icb",
".ico": "application/x-ico",
".iff": "application/x-iff",
".ig4": "application/x-g4",
".igs": "application/x-igs",
".iii": "application/x-iphone",
".img": "application/x-img",
".ins": "application/x-internet-signup",
".isp": "application/x-internet-signup",
".IVF": "video/x-ivf",
".java": "java/*",
".jfif": "image/jpeg",
".jpe": "application/x-jpe",
".jpeg": "image/jpeg",
".jpg": "application/x-jpg",
".js": "application/x-javascript",
".jsp": "text/html",
".la1": "audio/x-liquid-file",
".lar": "application/x-laplayer-reg",
".latex": "application/x-latex",
".lavs": "audio/x-liquid-secure",
".lbm": "application/x-lbm",
".lmsff": "audio/x-la-lms",
".ls": "application/x-javascript",
".ltr": "application/x-ltr",
".m1v": "video/x-mpeg",
".m2v": "video/x-mpeg",
".m3u": "audio/mpegurl",
".m4e": "video/mpeg4",
".mac": "application/x-mac",
".man": "application/x-troff-man",
".math": "text/xml",
".mdb": "application/x-mdb",
".mfp": "application/x-shockwave-flash",
".mht": "message/rfc822",
".mhtml": "message/rfc822",
".mi": "application/x-mi",
".mid": "audio/mid",
".midi": "audio/mid",
".mil": "application/x-mil",
".mml": "text/xml",
".mnd": "audio/x-musicnet-download",
".mns": "audio/x-musicnet-stream",
".mocha": "application/x-javascript",
".movie": "video/x-sgi-movie",
".mp1": "audio/mp1",
".mp2": "audio/mp2",
".mp2v": "video/mpeg",
".mp3": "audio/mp3",
".mp4": "video/mpeg4",
".mpa": "video/x-mpg",
".mpd": "application/vnd.ms-project",
".mpe": "video/x-mpeg",
".mpeg": "video/mpg",
".mpg": "video/mpg",
".mpga": "audio/rn-mpeg",
".mpp": "application/vnd.ms-project",
".mps": "video/x-mpeg",
".mpt": "application/vnd.ms-project",
".mpv": "video/mpg",
".mpv2": "video/mpeg",
".mpw": "application/vnd.ms-project",
".mpx": "application/vnd.ms-project",
".mtx": "text/xml",
".mxp": "application/x-mmxp",
".net": "image/pnetvue",
".nrf": "application/x-nrf",
".nws": "message/rfc822",
".odc": "text/x-ms-odc",
".out": "application/x-out",
".p10": "application/pkcs10",
".p12": "application/x-pkcs12",
".p7b": "application/x-pkcs7-certificates",
".p7c": "application/pkcs7-mime",
".p7m": "application/pkcs7-mime",
".p7r": "application/x-pkcs7-certreqresp",
".p7s": "application/pkcs7-signature",
".pc5": "application/x-pc5",
".pci": "application/x-pci",
".pcl": "application/x-pcl",
".pcx": "application/x-pcx",
".pdf": "application/pdf",
".pdx": "application/vnd.adobe.pdx",
".pfx": "application/x-pkcs12",
".pgl": "application/x-pgl",
".pic": "application/x-pic",
".pko": "application/vnd.ms-pki.pko",
".pl": "application/x-perl",
".plg": "text/html",
".pls": "audio/scpls",
".plt": "application/x-plt",
".png": "application/x-png",
".pot": "application/vnd.ms-powerpoint",
".ppa": "application/vnd.ms-powerpoint",
".ppm": "application/x-ppm",
".pps": "application/vnd.ms-powerpoint",
".ppt": "application/x-ppt",
".pr": "application/x-pr",
".prf": "application/pics-rules",
".prn": "application/x-prn",
".prt": "application/x-prt",
".ps": "application/postscript",
".ptn": "application/x-ptn",
".pwz": "application/vnd.ms-powerpoint",
".r3t": "text/vnd.rn-realtext3d",
".ra": "audio/vnd.rn-realaudio",
".ram": "audio/x-pn-realaudio",
".ras": "application/x-ras",
".rat": "application/rat-file",
".rdf": "text/xml",
".rec": "application/vnd.rn-recording",
".red": "application/x-red",
".rgb": "application/x-rgb",
".rjs": "application/vnd.rn-realsystem-rjs",
".rjt": "application/vnd.rn-realsystem-rjt",
".rlc": "application/x-rlc",
".rle": "application/x-rle",
".rm": "application/vnd.rn-realmedia",
".rmf": "application/vnd.adobe.rmf",
".rmi": "audio/mid",
".rmj": "application/vnd.rn-realsystem-rmj",
".rmm": "audio/x-pn-realaudio",
".rmp": "application/vnd.rn-rn_music_package",
".rms": "application/vnd.rn-realmedia-secure",
".rmvb": "application/vnd.rn-realmedia-vbr",
".rmx": "application/vnd.rn-realsystem-rmx",
".rnx": "application/vnd.rn-realplayer",
".rp": "image/vnd.rn-realpix",
".rpm": "audio/x-pn-realaudio-plugin",
".rsml": "application/vnd.rn-rsml",
".rt": "text/vnd.rn-realtext",
".rtf": "application/x-rtf",
".rv": "video/vnd.rn-realvideo",
".sam": "application/x-sam",
".sat": "application/x-sat",
".sdp": "application/sdp",
".sdw": "application/x-sdw",
".sit": "application/x-stuffit",
".slb": "application/x-slb",
".sld": "application/x-sld",
".slk": "drawing/x-slk",
".smi": "application/smil",
".smil": "application/smil",
".smk": "application/x-smk",
".snd": "audio/basic",
".sol": "text/plain",
".sor": "text/plain",
".spc": "application/x-pkcs7-certificates",
".spl": "application/futuresplash",
".spp": "text/xml",
".ssm": "application/streamingmedia",
".sst": "application/vnd.ms-pki.certstore",
".stl": "application/vnd.ms-pki.stl",
".stm": "text/html",
".sty": "application/x-sty",
".svg": "text/xml",
".swf": "application/x-shockwave-flash",
".tdf": "application/x-tdf",
".tg4": "application/x-tg4",
".tga": "application/x-tga",
".tiff": "image/tiff",
".tld": "text/xml",
".top": "drawing/x-top",
".torrent": "application/x-bittorrent",
".tsd": "text/xml",
".txt": "text/plain",
".uin": "application/x-icq",
".uls": "text/iuls",
".vcf": "text/x-vcard",
".vda": "application/x-vda",
".vdx": "application/vnd.visio",
".vml": "text/xml",
".vpg": "application/x-vpeg005",
".vsd": "application/x-vsd",
".vss": "application/vnd.visio",
".vst": "application/x-vst",
".vsw": "application/vnd.visio",
".vsx": "application/vnd.visio",
".vtx": "application/vnd.visio",
".vxml": "text/xml",
".wav": "audio/wav",
".wax": "audio/x-ms-wax",
".wb1": "application/x-wb1",
".wb2": "application/x-wb2",
".wb3": "application/x-wb3",
".wbmp": "image/vnd.wap.wbmp",
".wiz": "application/msword",
".wk3": "application/x-wk3",
".wk4": "application/x-wk4",
".wkq": "application/x-wkq",
".wks": "application/x-wks",
".wm": "video/x-ms-wm",
".wma": "audio/x-ms-wma",
".wmd": "application/x-ms-wmd",
".wmf": "application/x-wmf",
".wml": "text/vnd.wap.wml",
".wmv": "video/x-ms-wmv",
".wmx": "video/x-ms-wmx",
".wmz": "application/x-ms-wmz",
".wp6": "application/x-wp6",
".wpd": "application/x-wpd",
".wpg": "application/x-wpg",
".wpl": "application/vnd.ms-wpl",
".wq1": "application/x-wq1",
".wr1": "application/x-wr1",
".wri": "application/x-wri",
".wrk": "application/x-wrk",
".ws": "application/x-ws",
".ws2": "application/x-ws",
".wsc": "text/scriptlet",
".wsdl": "text/xml",
".wvx": "video/x-ms-wvx",
".xdp": "application/vnd.adobe.xdp",
".xdr": "text/xml",
".xfd": "application/vnd.adobe.xfd",
".xfdf": "application/vnd.adobe.xfdf",
".xhtml": "text/html",
".xls": "application/x-xls",
".xlw": "application/x-xlw",
".xml": "text/xml",
".xpl": "audio/scpls",
".xq": "text/xml",
".xql": "text/xml",
".xquery": "text/xml",
".xsd": "text/xml",
".xsl": "text/xml",
".xslt": "text/xml",
".xwd": "application/x-xwd",
".x_b": "application/x-x_b",
".sis": "application/vnd.symbian.install",
".sisx": "application/vnd.symbian.install",
".x_t": "application/x-x_t",
".ipa": "application/vnd.iphone",
".apk": "application/vnd.android.package-archive",
".xap": "application/x-silverlight-app"
}
三、 总结
写一个 nodejs npm应用 - webhere的更多相关文章
- linux下面配置安装nodejs+npm
linux下 多亏这一篇文章= =我就卡死在文章所说的这个点里 附大牛链接:http://blog.sitearth.com/nodejs%E4%B8%8A%E4%BD%BF%E7%94%A8mong ...
- 怎么样写一个能告诉你npm包名字是否被占用的工具
事情是这样的: 因为我经常会写一些npm包,但是有时候我写完一个包,npm publish 的时候却被提示说包名字被占用了,要不就改名字,要不就加scope,很无奈.npm 命令行可以通过 npm v ...
- 用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具
用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具 前言 上周,同事抱怨说 react 怎么不能像 angular 那样,使用命令行工具来生成一个组件.对呀,平时工作时,想要创建 ...
- 通过npm写一个cli命令行工具
前言 如果你想写一个npm插件,如果你想通过命令行来简化自己的操作,如果你也是个懒惰的人,那么这篇文章值得一看. po主的上一篇文章介绍了定制自己的模版,但这样po主还是不满足啊,项目中我们频繁的需要 ...
- 从零开始写一个npm包及上传
最近刚好自己需要写公有npm包及上传,虽然百度上资料都能找到,但是都是比较零零碎碎的,个人就来整理下,如何从零开始写一个npm包及上传. 该篇文件只记录一个大概的流程,一些细节没有记录. tips: ...
- 我想写一个前端开发工具(一):在npm发布模块
有必要说说我为什么要开始写这个,正文从下面的第一条开始 我最近忙于公司的项目,一直没有抽出时间来写文章.本来想每个月写一片文章,保质保量,无奈上个月没有坚持. 这段时间有点忙,主要是由于公司业务调整, ...
- 从零开始写一个npm包,一键生成react组件(偷懒==提高效率)
前言 最近写项目开发新模块的时候,每次写新模块的时候需要创建一个组件的时候(包含组件css,index.js,组件js),就只能会拷贝其他组件修改名称 ,但是写了1-2个后发现效率太低了,而且极容易出 ...
- 80行代码教你写一个Webpack插件并发布到npm
1. 前言 最近在学习 Webpack 相关的原理,以前只知道 Webpack 的配置方法,但并不知道其内部流程,经过一轮的学习,感觉获益良多,为了巩固学习的内容,我决定尝试自己动手写一个插件. 这个 ...
- [NodeJS]使用Node.js写一个简单的在线聊天室
声明:教程来自<Node即学即用>.源代码案例均出自此书.博文仅为个人学习笔记. 第一步:创建一个聊天server. 首先,我们先来写一个Server: var net = require ...
随机推荐
- Druid 数据库连接池监控配置(web项目)
Spring数据源配置: <!-- 数据源 --> <!--<bean id="dataSource" class="org.apache.com ...
- 批处理脚本为Mysql重置root密码(重置密码为123456)
@echo off title mysql ::从注册表找到Mysql的安装路径写入文件mysql.txt reg query HKLM\SYSTEM\ControlSet001\Services\M ...
- 关于SUID、SGID、Sticky
SUID属性 passwd命令可以用于更改用户的密码,一般用户可以使用这个命令修改自己的密码.但是保存用户密码的/etc/shadow文件的权限是400,也就是说只有文件的所有者root用户可以写入, ...
- android ListView 和 BaseAdapter 应用
步聚: 1.建立ListView对象:--(作用:绑定Adapter呈现数据) 2.建立ListView实现的Item栏位.xml布局:--(作用:实现ListView的栏位布局) 3.建立Item. ...
- android 布局下划线
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_cont ...
- 非常不错的点餐系统应用ios源码完整版
该源码是一款非常不错的点餐系统应用,应用源码齐全,运行起来非常不错,基本实现了点餐的一些常用的功能,而且界面设计地也很不错,是一个不错的ios应用学习的例子,喜欢的朋友可以下载学习看看,更多ios源码 ...
- 9、FTP封杀用户、限制传输速率、限制访问目录、为匿名用户提供下载资源
一.封杀某些用户访问FTP服务器 例如 封杀 yanji [root@localhost root]# vi /etc/vsftpd.ftpusers (用户控制配置文件,主要用于限 ...
- Oracle Dataguard的原理与基本配置
最近集团在做灾备方案,用于Oracle的高可用性,在不影响主库性能的前提下,我们选择使用DG的"最大性能"模式. DG是Oracle数据库自带的数据同步功能,其基本原理是将日志 ...
- plain framework 1 参考手册 入门指引之 代码风格
代码风格 介绍 介绍 框架自身采用了google的C++风格,作者也鼓励在你的应用中使用此风格,有关此风格你可以查阅相关资料了解.下面是一段plain framework中的代码,以便大家参考: 你可 ...
- NOIP2007矩阵取数[DP|高精度]
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...