这是我第一次使用Node.js来编程,而且是构建一个一个静态文件资源访问的Http server。
我个人从事java相关的开发差不多有10年了吧,一直都是在构建后端的服务、应用。对于前端一直没有过多的接触。对于servlet、jsp等技术也仅限于工作的需要(包含struct等mvc框架)。
最近工作中,参与负责了公司产品Object-Centric理念的开发模式构建。利用Business model对象拉通前后端的开发体验,通过Business Model 对象组织所有和该业务模型对象关联的资源:实体模型、试图模型、服务(rest)、业务校验、数据转换处理、页面等。
目前由于参与到前端页面相关技术的构建和研究,突然对这方面的技术产生了浓厚的兴趣。对Node.js、AngularJS、TypeScript都有兴趣深入的学习和使用。后面打算再把mangodb纳入到学习计划中,这样就把MEAN技术拉通了:)。
下面就是我基于Node.js实现的一个简单的静态页面文件的http server,总体体验来说,在编码的高效性、灵活性等体验,对比java实现会好很多。但是在类型的识别、编译错误的识别、类型的提示上没有强语言类型的java来的好。
首先来看一下整个工程的目录结构:
目录说明:
HTTP_SERVER:整个工程的根目录;
app:静态文件存放的目录,对于我来说就是我“未来”期望一个web工程的根目录,对应于java构建web应用,就是web-app了。
css:用来存放样式定义文件
文件说明:
server.js:提供静态http服务的主程序。
mine.js:键值对的配置文件,定义了对不同的文件类型的处理定义。
index.html:web app中的首页,静态的html的文件。
indx.css:index.html首页引用的层叠样式表的定义文件。
首先来看一下server.js的实现:
var http = require('http'); var url = require('url'); var fs = require('fs'); // 自己定义的类型定义文件 var mine = require('./mine').types; var path = require('path'); var port = '3000'; var hostname = '127.0.0.1'; var server = http.createServer((req, res) => { var pathName = url.parse(req.url).pathname; // url.parse会将一个请求的路径解析为格式化的输出 /* { protocol : 'http' , auth : null , host : 'example.com:8080' , port : '8080' , hostname : 'example.com' , hash : null , search : '?a=index&t=article&m=default', query : 'a=index&t=article&m=default', pathname : '/one', path : '/one?a=index&t=article&m=default', href : 'http://example.com:8080/one?a=index&t=article&m=default' } */ var realPath = path.join("app", pathName); console.log(realPath); var ext = path.extname(realPath); ext = ext ? ext.slice(1) : 'unknow'; // ext = ext ? ext.split('.')[1] : 'unknown'; fs.stat(realPath, (err, stats) => { if (err) { console.log(err); res.writeHead(404, { 'Content-Type': 'text/plain' }); res.write(`This request URL ${pathName} was not found on this server.`); res.end(); } else { fs.readFile(realPath, "binary", (err, data) => { if (err) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end(err); } else { console.log(data); var contentType = mine[ext] || "text/plain"; res.writeHead(200, { 'Content-Type': contentType }); res.write(data, "binary"); res.end(); } }) console.log(stats); } }); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}`); })
代码的一点说明:
var ext = path.extname(realPath);
ext = ext ? ext.slice(1) : 'unknow';
这两句其实是通过截取访问路径的最后的字符串,来获取访问的文件类型。例如,下面的url:http://localhost:3000/index.html。通过这两句处理之后,ext内的值是html。如果url是:http://localhost:3000/index,那么ext的值就是unknow。
fs.stat(realPath, (err, stats) => {
}
这个里面的处理,是我不同于网上参考实现的处理。是我自己查阅了node.js的实现,根据node.js的说明文档自己添加的,其实就是对文件的一个预处理,防止对文件直接操作抛出异常。
再看一下mine.js的代码实现:
exports.types = { "html": "text/html", "xml": "text/xml", "js": "text/javascript", "css": "text/css", "json": "application/json", "txt": "text/plain", "pdf": "application/pdf", "doc": "application/msword", "xls": "application/vnd.ms-excel", "ico": "image/x-icon", "jpeg": "image/jpeg", "jpg": "image/jpeg", "png": "image/png", "bmp": "image/bmp", "svg": "image/svg+xml", "tiff": "image/tiff", "gif": "image/gif", "swf": "application/x-shockwave-flash", "wav": "audio/x-wav", "wma": "audio/x-ms-wma", "mp3": "audio/mpeg", "wmv": "video/x-ms-wmv", "avi": "video/x-msvideo", "gz": "application/x-gzip", "manifest": "text/cache-manifest" };
这个文件没什么好说的,主要是还i应用在返回时,设置httpheader的内容使用。
再看一下html,这个也是我参考了网上的实现,不过我稍微做了一点改造,增加了一点javascript的代码做测试:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>春晓</title>
<link href="./css/index.css" rel="stylesheet" type="text/css">
<script>
function displayDate() {
document.getElementById("demo").innerHTML = Date();
}
</script>
</head>
<body>
<nav>春晓</nav>
<div id="value">
<p>春眠不觉晓</p>
<p>处处闻啼鸟</p>
<p>夜来风雨声</p>
<p>花落知多少</p>
</div>
<h1>My First JavaScript</h1>
<p id="demo">This is a paragraph.</p>
<button type="button" οnclick="displayDate()">
Display Date</button>
</body>
</html>
再把css的定义文件贴上来,其实也是我参考网上的实现:
body{
background-color:#222222;
}
nav {
color:#cc0000;
font-weight:bold;
font-size:2em;
}
#value{
color:#cc0000;
font-size:2.1em;
}
运行server.js:
首先通过命令行,进入到工程的根目录下:
我是在vsc(visula stuido code)中,直接选中server.js右键选择〔在命令提示符中打开〕
在命令中输入node server.js
回车后,启动服务,并看到日志输出:
在浏览器中输入:http://localhost:3000/index.html得到的页面:
就可以正常看到我们定义的app目录下的index.html文件,同时在这个文件中定义的js也可以正常运行。
总结:使用node.js的确可以快速、高效的完成前端的开发,相对于java很高效。同时,对于我习惯于java开发的人来说,里面的一些语法、写法确实有些不太习惯。
下一步,是准备利用express这个框架来搭建相同的静态http server的实现。
在下一步就是构建基于mongodb的小应用了,最后在引入typeScript,嘿嘿,还是挺有意思的。