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入门这本教程。这之中提到了许多好的文章,我来总结下:

马上就要进行实习生考核了,好忧桑,实习的时间过得好快啊,不舍的感觉很浓厚啊。

Node.js下的Hello World的更多相关文章

  1. node.js 下依赖Express 实现post 4种方式提交参数

    上面这个图好有意思啊,哈哈, v8威武啊.... 在2014年的最后一天和大家分享关于node.js 如何提交4种格式的post数据. 上上一篇说到了关于http协议里定义的4种常见数据的post方法 ...

  2. npm 是node.js下带的一个包管理工具

    npm 是node.js下带的一个包管理工具          npm install -g webpack webpack是一个打包工具 gulp是一个基于流的构建工具,相对其他构件工具来说,更简洁 ...

  3. node.js下操作cookie

    cookie,又是cookie.工作中与cookie打交道很多次,不过时间跨度也大,每总结多一次,就加深了解多一点. cookie,一定是放在浏览器中的,用于浏览器保存一些小额度的内容.每次我们去访问 ...

  4. node.js下使用RSA加密事例(windows)

    1.安装openss 直接下载window下的安装包 http://houjixin.blog.163.com/blog/static/3562841020144143494875/ 以我发博文现在的 ...

  5. 深入浅出Node.js(下)

    (五):Node.js的异步实现 专栏的第五篇文章<Node.js的异步实现>.之前介绍了Node.js的事件机制,也许读者对此尚会觉得意犹未尽,因为仅仅只是简单的事件机制,并不能道尽No ...

  6. node.js 下使用 util.inherits 来实现继承

    上一篇博客说到了node.js继承events类实现事件发射和事件绑定函数,其中我们实现了一个公用基类 _base ,然后在模型中差异化的定义了各种业务需要的模型并继承 _base 公共基类.但是其中 ...

  7. node.js下LDAP查询实践

    目标: 从一个LDAP Server获取uid=kxh的用户数据 LDAP地址为:ldap://10.233.21.116:389 在工程根目录中,先npm一个LDAP的访问库ldpajs npm i ...

  8. node.js下when.js(Promises/A)的实践

    假设一个业务场景: 通过rss地址,获取rss并保存于文件,rss地址保存于文件中. 完成该场景的业务需要完成3个任务: 1.从文件中读取rss地址. 2.获取rss. 3.保存于文件. 最后将这三个 ...

  9. Node.js下基于Express + Socket.io 搭建一个基本的在线聊天室

    一.聊天室简单介绍 采用nodeJS设计,基于express框架,使用WebSocket编程之 socket.io机制.聊天室增加了 注册登录模块 ,并将用户个人信息和聊天记录存入数据库. 数据库采用 ...

随机推荐

  1. autofac 在.net core 与经典asp.net中的差异

    前提: Install-Package Microsoft.Extensions.DependencyInjection 特點: 使用nstancePerLifetimeScope代替Instance ...

  2. UVA - 10494 If We Were a Child Again

    用java写的大数基本操作,java要求的格式比较严谨. import java.util.*; import java.math.*; public class Main { public stat ...

  3. 2017ACM暑期多校联合训练 - Team 8 1002 HDU 6134 Battlestation Operational (数论 莫比乌斯反演)

    题目链接 Problem Description The Death Star, known officially as the DS-1 Orbital Battle Station, also k ...

  4. 2017ACM暑期多校联合训练 - Team 5 1006 HDU 5205 Rikka with Graph (找规律)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  5. python3学习笔记.2.基础

    1.编码 默认编码是 utf-8 # -*- coding: utf-8 -*- 2.注释 单行注释  # 多行注释,用三个单引号或双引号 3.关键字 可在交互窗口查询. >>> i ...

  6. 一文掌握关于Java数据结构所有知识点(欢迎一起完善)

    在我们学习Java的时候,很多人会面临我不知道继续学什么或者面试会问什么的尴尬情况(我本人之前就很迷茫).所以,我决定通过这个开源平台来帮助一些有需要的人,通过下面的内容,你会掌握系统的Java学习以 ...

  7. nginx同域名动静态分离

    公司需求是如果是app加载静态页面的话要通过应用服务直接请求指定的服务  由于机房迁移  不得不将该文件迁移到一个指定的地方  需要通过nginx配置检测到是访问该静态页面的就转到该静态页面上面进行加 ...

  8. [ python ] 各种推导式

    各种推导式,主要使用示例演示用法 列表生成式 示例1:求0-9每个数的平方 li = [x*x for x in range(10)] print(li) # 执行结果: # [0, 1, 4, 9, ...

  9. npm install 装本地一直安装全局问题

    想用npm安装一些模块,不管怎么装,一直装作全局. 以为是node有问题,重装了N次,却还发现这个问题. 困惑几天无果, 偶然间通过此文章发现,npm存在配置文件:https://www.sitepo ...

  10. CSU 1356 Catch

    原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1356 题目需要我们判断给定图在某一步是否会有可能出现在所有节点.首先,我们不妨假设给定图 ...