Node.js下的Hello World
Node.js技术现在可谓是如火如荼,前后端都统一为Javascript的体验绝对是受到了很多人的青睐,我都后悔以前没抽时间好好学一学Javascript了。
首先,我来介绍一下Node.js。本人实在是才疏学浅,对技术的认识不够,所以就借鉴了血多InfoQ上的好文,后面会给出链接。
Node.js采用C++语言编写而成,是一个Javascript的运行环境。重点就在这个运行环境四个字上。意思就是,你编写好的Js后端服务器代码,要通过Node来运行。拿Windows下来说,比如你要运行hello.js的后台代码,可以如下:
D:\Nodejs>node hello.js
如果你代码没有错误的话,你就成功的运行了这个服务器。
关于Node.js的优势与特色,大家大可去google下,有很多前辈的文章都说明的非常清楚,总而言之,Node.js采用事件驱动、异步编程,为网络服务而设计,始终保持单线程,通过事件轮询,来实现并行操作。
下面,我为大家介绍一个简单的Node.js示例。我自己也是学习的Node.js入门,这真的是针对初学者的教程,如果想亲自实践下Node.js的同学,完全可以忽视下面的内容,直接跳到该教程实践。
下面说一下我的文件结构:
- index.js //入口文件,包含了对应url和调用方法的字典
- server.js //服务端启动文件
- router.js //路由文件,包含了路由的解析
- requestHandler.js //请求处理文件,包含了请求处理的逻辑
来看下代码吧>.<
//index.js
var server = require("./server");
var route = require("./router");
var requestHandlers = require("./requestHandlers"); var handle = {};
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload; server.start(route.route, handle);
稍微解释下,前面3个require语句,代表了使用对应的3个模块,而且这三个模块是我自己定义的,取得模块后就能方便的调用其中的方法了。随后定义了handle字典,其中的key代表着可以识别的url中的path,value表示应用分发到的处理逻辑。最后一行的server.start()表示启动服务,至于参数的含义就移步到server.js中就明白了。
//server.js
var http = require("http");
var url = require("url"); function start(route, handle){
function onRequest(request, response){
console.log("Reqeust received");
var pathname = url.parse(request.url).pathname;
console.log("Reqeust for " + pathname + " received"); //route(handle, pathname, response);
request.setEncoding("utf-8");
var postData = '';
request.addListener("data", function(postDataChunk) {
postData += postDataChunk;
console.log("Received Post Data chunk '"+postDataChunk+"'.");
}); request.addListener("end", function() {
route(handle, pathname, response, postData);
});
} http.createServer(onRequest).listen(8888);
console.log("Server has Started");
} exports.start = start ;
同样解释下,首先是包含进两个系统内置的包,这两个也是Node.js应用最最基本的包了,一个负责http的相关事务,一个负责url的内容。之后的start方法,仅仅是做了一层封装,最核心的逻辑还是在onRequest方法之中。console.log()都只是为了在控制台输出,方便理清运行逻辑,对功能没有影响,可以无视掉。pathname变量就是通过url得到请求的path路径。addListener方法是添加监听器,当请求是post方法包含数据时,监听器就会监听到,并回调参数中传递的方法。都很好理解,data事件是收集传过来的数据,end事件是把请求和数据一起分发到route那边去。然后http.createServer(onRequest).listen(8888);这一段是告诉服务器,每当有请求过来时就传给onRequest方法,同时是监听本地的8888端口。最后的exports.start 是打包操作,大家可以从index.js中略知一二。
//router.js
function route(handle, pathname, response, postData){
console.log("About to route a request for "+ pathname);
if(typeof handle[pathname] === 'function'){
return handle[pathname](response, postData);
}else{
console.log("No request handler found for "+ pathname);
response.writeHead(404, {"Content-type": "text/plain"});
response.write("404 Not found");
response.end();
}
} exports.route = route;
来解释下router.js这个文件。很简单,只包含了一个route的处理逻辑。我们来看一下参数,handle是从index.js中传过来的请求处理字典,pathname是从server.js中传过来的路径,response同样是server传来的响应,你的服务器要做什么样的应答,都在response中了,最后的postData就是post请求中的数据,也是从server那边传过来。再来看下具体逻辑,实现判断请求路径是否在字典中,在并且能找到处理方法,那么直接返回调用这个方法,并把response和postData传过去;如果找不到,表示不支持这个请求,返回字符串Not found。writeHead方法是写入响应的首部,很简单。最后同样是把route这个方法打包出去。
// requestHandlers.js
var querystring = require("querystring"); function start(response, postData){
console.log("Request handler 'start' was called"); var body = '<html>'+
'<head>'+
'<meta http-equiv="Content-Type" content="text/html; '+
'charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" method="post">'+
'<textarea name="text" rows="20" cols="60"></textarea>'+
'<input type="submit" value="Submit text" />'+
'</form>'+
'</body>'+
'</html>'; response.writeHead(200, {"Content-Type": "text/html"});
response.write(body);
response.end();
} function upload(response, postData){
console.log("Request handler 'upload' was called.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("You've sent: " + querystring.parse(postData).text);
response.end();
} exports.start = start;
exports.upload = upload;
来看下最后一个文件,requestHandlers.js。这个文件主要负责每个请求的详细处理逻辑了,首先引用进来的是一个内置的包,可以处理get或则post请求中的数据,顾名思义嘛,querystring。第一个方法是start方法,是改Node应用的默认方法,很简单,直接在response中写入一段html代码,记得别忘记调用response.end方法,表示响应到此结束。
第二个upload方法,是将从start界面中输入的字符串展示出来,也非常简单。因为数据postData处理在server.js中就已经进行过了,这里只是一个简单的拼接,并直接输出到页面之中。这里可以稍微注意下querystring包的用法,parse是分析这段数据,得到一个对象。注意到之前的textarea的命名是text,所以在这取text属性,就能得到传过来的数据了。
到此,整个代码就展示的差不多了,然后只用转到对应文件目录下的控制台,输入node index.js 回车,就能看到服务器成功运行了,前提是代码是正确的。
打开浏览器,输入localhost:8888,就能看到自己的start界面了,输入一段文本submit,跳到upload页面,也很成功的展示了该段文本。一个简单的helloworld就这样ok了,要在这之上添加功能也是非常容易的。不过最好是研究下是MVC的实践,这样才能让人舒心啊。再次强调感谢下Node入门这本教程。这之中提到了许多好的文章,我来总结下:
- 官方安装指南
- Understanding node.js
- Martin Fowlers关于依赖注入的大作
- 理解函数编程
- 理解node.js的事件轮询
- Node.js社区的wiki
- 深入浅出Node.js系列文章
马上就要进行实习生考核了,好忧桑,实习的时间过得好快啊,不舍的感觉很浓厚啊。
Node.js下的Hello World的更多相关文章
- node.js 下依赖Express 实现post 4种方式提交参数
上面这个图好有意思啊,哈哈, v8威武啊.... 在2014年的最后一天和大家分享关于node.js 如何提交4种格式的post数据. 上上一篇说到了关于http协议里定义的4种常见数据的post方法 ...
- npm 是node.js下带的一个包管理工具
npm 是node.js下带的一个包管理工具 npm install -g webpack webpack是一个打包工具 gulp是一个基于流的构建工具,相对其他构件工具来说,更简洁 ...
- node.js下操作cookie
cookie,又是cookie.工作中与cookie打交道很多次,不过时间跨度也大,每总结多一次,就加深了解多一点. cookie,一定是放在浏览器中的,用于浏览器保存一些小额度的内容.每次我们去访问 ...
- node.js下使用RSA加密事例(windows)
1.安装openss 直接下载window下的安装包 http://houjixin.blog.163.com/blog/static/3562841020144143494875/ 以我发博文现在的 ...
- 深入浅出Node.js(下)
(五):Node.js的异步实现 专栏的第五篇文章<Node.js的异步实现>.之前介绍了Node.js的事件机制,也许读者对此尚会觉得意犹未尽,因为仅仅只是简单的事件机制,并不能道尽No ...
- node.js 下使用 util.inherits 来实现继承
上一篇博客说到了node.js继承events类实现事件发射和事件绑定函数,其中我们实现了一个公用基类 _base ,然后在模型中差异化的定义了各种业务需要的模型并继承 _base 公共基类.但是其中 ...
- node.js下LDAP查询实践
目标: 从一个LDAP Server获取uid=kxh的用户数据 LDAP地址为:ldap://10.233.21.116:389 在工程根目录中,先npm一个LDAP的访问库ldpajs npm i ...
- node.js下when.js(Promises/A)的实践
假设一个业务场景: 通过rss地址,获取rss并保存于文件,rss地址保存于文件中. 完成该场景的业务需要完成3个任务: 1.从文件中读取rss地址. 2.获取rss. 3.保存于文件. 最后将这三个 ...
- Node.js下基于Express + Socket.io 搭建一个基本的在线聊天室
一.聊天室简单介绍 采用nodeJS设计,基于express框架,使用WebSocket编程之 socket.io机制.聊天室增加了 注册登录模块 ,并将用户个人信息和聊天记录存入数据库. 数据库采用 ...
随机推荐
- 在ASP.NET中备份和还原数据库
昨天看了<C#项目实录>中的进销存管理系统,和其他书里讲的案例一样,无非也就是数据库增删查改,但是这个进销存系统中有一个备份和还原数据库的功能,蛮有兴趣的,看了一下代码,原来如此, ...
- 数组B - 我想我需要一艘船屋
[题目大意]弗雷德先生正在考虑在路易斯安娜州买一块地造房子,在土地调查中,他了解到由于密西西比河的侵蚀,路易斯安那州正以每年50平方英里的速度变小.弗雷德先生想知道他买的那块地是否会被侵蚀掉,经过进一 ...
- favico.js笔记
1. favicon.js是什么 一个js库可以使用徽标.图像.视频等来设置网页的favicon,即网页标题栏上的小图标. 2. 如何使用 2.1 使用徽标 basic demo: <!DOCT ...
- JSON.parse()——json字符串转JS
JSON 通常用于与服务端交换数据. 在接收服务器数据时一般是字符串. 我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象. 语法 JSON.parse(text[, ...
- Linux mint 18.1 / Ubuntu 16.04 安装steam
这里以Limit Mint 18.1为例: 安装steam: sudo dpkg -i steam.deb 运行后会有如下错误: 直接运行如下命令修复, 并自动启动steam: LD_PRELOAD= ...
- 有关mysql的innodb_flush_log_at_trx_commit参数【转】
一.参数解释 0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下在事务提交的时候,不会主动触发写入磁盘的操作. 1:每次事务 ...
- ASP连接读写ACCESS数据库实例(转)
(一) 数据库的选择:有许多的数据库你可以选择,SQL SERVER.ACCESS(*.mdb).EXCEL(*.xls).FOXPRO(*.dbf)甚至普通的文本文件(*.txt)都可以达到存储 ...
- intellij idea 远程tomcat 调试
由于在服务器上远程调试风险较高,所以万不得已的情况下 不要这样做.可以本地调试好 再上传到服务器上. 1.关闭防火墙 启动Firewalld,及开机自启. # systemctl start fir ...
- TCP可靠传输和拥塞控制
1.TCP的可靠传输 tcp的可靠传输主要靠 来自接收方的确认报文 和 超时重传. 发出报文,计时器开始计时,在规定超时时间内未收到确认报文则重新发送. 注意:发送报文都留一个副本,如果收到确认报文就 ...
- 使用Nginx代理Django
一.准备环境 检查python版本以及pip版本 [root@linux-node01 src]# python --version Python 2.7.5 [root@linux-node01 s ...