Node开发入门
介绍
Node.js采用google的V8虚拟机来解释和执行javascript,也就是允许脱离浏览器环境运行javascript代码。
Hello World
婴儿说的第一个字一般是“妈”,程序员写的第一行代码肯定是“hello world”。
创建helloworld.js文件,输入如下代码:
console.log("Hello world!");
然后使用node来执行:
node helloworld.js
终端便输出了“Hello world!”
构建http服务器
脱离了无聊的hello world,我们再来看看怎么搭建一个网站,搭建网站首先需要构建一个基础的http服务器。
这里我们要用到http模块,http是node的内置模块,引用也非常简单:
var http = require("http");
然后我们再新建一个server.js文件,在里面输入:
var http = require("http");
http.createServer(function(request, response){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello world");
response.end();
}).listen(8080);
输入完成后,首先用node.js执行:
node server.js
然后打开浏览器,访问http://localhost:8080/, 然后你就能在页面上看到“Hello world”了。
不是说好脱离hello world了吗,怎么还来?不用急,马上就不是了。
创建自己的模块
现在还只是一个基础的http服务器,除了显示一个hello world以外没有任何价值(当然显示hello world也没什么价值),但是当代码量越来越大时,全放在一个文件里会显得很混乱,怎么办呢?
我们之前已经用过node内置的http模块,那么我们能不能自己创建模块呢?答案是能,不能还说这么多废话干什么。
打开server.js文件,定义一个start函数,该函数包含http服务器代码,然后再将函数导出:
var http = require("http");
function start() {
function onRequest(request, response){
console.log("request received");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hi world"); //说过不用hello world
response.end();
}
http.createServer(onRequest).listen(8080);
console.log("Server has started");
}
exports.start = start;
那怎么去调用这个模块呢?和调用node内置模块类似,先新建一个文件index.js,然后输入如下代码:
var server = require("./server");
server.start();
这次我们不再运行server.js了,而是运行index.js:
node index.js
然后再打开浏览器,访问http://localhost:8080/, 这次我们将不会再看见hello world,而是看见hi world。
路由
我们在浏览器访问http://localhost:8080/ ,我们将在页面上看见hi world,我们访问http://localhost:8080/sb, 看到的依然是hi world,这是怎么回事呢?怎么让我访问不同的地址进入到不同的页面呢?
这里我们就需要创建路由,使路由根据请求的不同的url和get及post参数来执行不同的代码。
先新建一个router.js,添加以下内容:
function route (pathname){
console.log("request for " + pathname);
};
exports.route = route;
然后修改server.js,给onRequest函数增加一些代码,这里我们需要用到url模块:
var http = require("http"), url = require("url");
function start(route) {
function onRequest(request, response){
var pathname = url.parse(request.url).pathname;
console.log("request for " + pathname + " received");
route(pathname);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hi world"); //说过不用hello world
response.end();
}
http.createServer(onRequest).listen(8080);
console.log("Server has started");
}
exports.start = start;
当然,也要修改index.js,将路由函数注入到服务器中:
var server = require("./server"), router = require("./router");
server.start(router.route);
这样路由的基本功能就完成了,但是路由貌似还是什么事也没有做。
给路由增加处理程序
路由的功能应该是针对不同的url有着不同的处理方式,例如处理http://localhost:8080/ 和处理localhost:8080/sb是不一样的。
我们再增加一个请求处理的模块,新建requestHandlers.js,定义两个函数,并接受response参数:
function start(response){
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Start!");
response.end();
}
function sb(response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Fuck sb!")
response.end();
}
exports.start = start;
exports.sb = sb;
javascript的对象就是一个键值对的集合,这里的值可以是任何类型,包括函数,我们可以在index.js中这样引入:
var server = require("./server"),
router = require("./router"),
requestHandlers = require("./requestHandlers");
var handle = {};
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/sb"] = requestHandlers.sb;
server.start(router.route, handle);
然后修改server.js:
var http = require("http"), url = require("url");
function start(route, handle) {
function onRequest(request, response){
var pathname = url.parse(request.url).pathname;
console.log("request for " + pathname + " received");
route(handle, pathname, response);
}
http.createServer(onRequest).listen(8080);
console.log("Server has started");
}
exports.start = start;
相应的修改router.js:
function route(handle, pathname, response) {
console.log("request for " + pathname);
if (typeof handle[pathname] == "function") {
handle[pathname](response);
} else {
console.log("No request handler found for " + pathname);
response.writeHead(404, { "Content-Type": "text/html" });
response.write("404 Not found");
response.end();
}
};
exports.route = route;
然后我们就可以浏览器中看见不同的url请求进行了不同的处理。
请求http://localhost:8080/ 和http://localhost:8080/start, 页面则会显示“Start!”。
请求http://localhost:8080/sb, 页面则显示“Fuck sb!”。
请求http://localhost:8080/fucksb,页面则显示“404 Not found”。
处理post请求
那怎么处理post请求呢?
我们这次要做的就是在页面显示一个文本框,让用户输入,然后通过post请求提交给服务器,服务器接收到请求并将输入的内容输出到浏览器的页面中。
首先我们需要修改requestHandlers.js,让页面显示一个文本框,并通过form表单提交给服务器:
function start(response) {
var body = '<html>' +
'<head>' +
'<meta http-equiv="Content-Type" content="text/html; ' +
'charset=UTF-8" />' +
'</head>' +
'<body>' +
'<form action="/sb" method="post">' +
'<input type="text" name="text"/>' +
'<input type="submit" value="Submit text" />' +
'</form>' +
'</body>' +
'</html>';
response.writeHead(200, { "Content-Type": "text/html" });
response.write(body);
response.end();
}
function sb(response) {
response.writeHead(200, { "Content-Type": "text/plain" });
response.write("Fuck sb!")
response.end();
}
exports.start = start;
exports.sb = sb;
当用户提交表单时,就会触发/sb请求处理程序来处理post请求的问题,但是如果用户提交的数据很大甚至是一个文件,这种大数据量的请求必然会导致用户操作的阻塞,因此我们需要采用异步回调的方式来处理数据。
我们需要在request对象上注册监听(listener)。
继续修改server.js:
var http = require("http"), url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var postData = "";
var pathname = url.parse(request.url).pathname;
console.log("request for " + pathname + " received");
request.setEncoding("utf8");
request.addListener("data", function (postDataChunk) {
postData += postDataChunk;
});
request.addListener("end", function () {
route(handle, pathname, response, postData);
})
}
http.createServer(onRequest).listen(8080);
console.log("Server has started");
}
exports.start = start;
因为增加了post提交来的参数,因此我们需要修改router.js,将postData传递给处理程序:
function route(handle, pathname, response, postData) {
console.log("request for " + pathname);
if (typeof handle[pathname] === "function") {
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;
然后修改requestHandlers.js的sb函数,接收参数并将数据输出:
function start(response) {
var body = '<html>' +
'<head>' +
'<meta http-equiv="Content-Type" content="text/html; ' +
'charset=UTF-8" />' +
'</head>' +
'<body>' +
'<form action="/sb" method="post">' +
'<input type="text" name="text"/>' +
'<input type="submit" value="Submit text" />' +
'</form>' +
'</body>' +
'</html>';
response.writeHead(200, { "Content-Type": "text/html" });
response.write(body);
response.end();
}
function sb(response, postData) {
response.writeHead(200, { "Content-Type": "text/plain" });
response.write(postData);
response.end();
}
exports.start = start;
exports.sb = sb;
然后重新执行
node index.js
打开浏览器访问http://localhost:8080/, 并在文本框中输入“sb”,点击提交,就会跳转到/sb页面,显示“text=sb”。
好像混进了奇怪的东西,我明明输入的sb,显示的为什么会是“text=sb”?
这是因为点击submit后,将整个form表单信息都提交过去了(如果form中还有其他内容也会一并提交),这里我们只关心文本框中的text信息,可以使用querystring模块来处理:
var text = querystring.parse(postData).text;
完整代码如下:
var querystring = require("querystring");
function start(response) {
var body = '<html>' +
'<head>' +
'<meta http-equiv="Content-Type" content="text/html; ' +
'charset=UTF-8" />' +
'</head>' +
'<body>' +
'<form action="/sb" method="post">' +
'<input type="text" name="text"/>' +
'<input type="submit" value="Submit text" />' +
'</form>' +
'</body>' +
'</html>';
response.writeHead(200, { "Content-Type": "text/html" });
response.write(body);
response.end();
}
function sb(response, postData) {
response.writeHead(200, { "Content-Type": "text/plain" });
response.write(querystring.parse(postData).text);
response.end();
}
exports.start = start;
exports.sb = sb;
一个简单的http服务器就构建完毕了。
结语
本文参考The Node Beginner Book,算是这本书的阉割版吧。这本书是node很好的入门书(或者说手册?),代码虽然简单,但却涵盖很多入门的技术点。
Node开发入门的更多相关文章
- Node.js开发入门—使用cookie保持登录
这次来做一个站点登录的小样例,后面会用到. 这个演示样例会用到Cookie.HTML表单.POST数据体(body)解析. 第一个版本号,我们的用户数据就写死在js文件中. 第二个版本号会引入Mong ...
- Node.js开发入门—HelloWorld再分析
在Node.js开发入门(1)我们用http模块实现了一个简单的HelloWorld站点,这次我们再来细致分析下代码.了解很多其它的细节. 先看看http版本号的HelloWorld代码: 代码就是这 ...
- 《Node.js入门》CentOS 6.5下Node.js Web开发环境搭建笔记
近期想尝试一下英特尔的基于WebRTC协同通信开发套件,所以须要在本地搭建Node.js Web的开发測试环境. 这里讲的是CentOS 下的搭建方法.使用Windows的小伙伴请參考: <No ...
- Node.js开发入门—使用AngularJS
做一个Web应用,一般都有前台和后台,Node.js能够实现后台.利用jade模板引擎也能够生成一些简单的前台页面,但要想开发出具有实际意义的现代Web应用.还得搭配一个Web前端框架. Angula ...
- HTML5手机APP开发入门(1)
HTML5手机APP开发入门(1) 开发框架 Ionicframework V2 + Angular 2 具体内容可以参考一下网站 http://ionicframework.net/ http:// ...
- Node.js 入门手册:那些最流行的 Web 开发框架
这篇文章与大家分享最流行的 Node.js Web 开发框架.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编 ...
- 【特别推荐】Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- 基于Nodejs生态圈的TypeScript+React开发入门教程
基于Nodejs生态圈的TypeScript+React开发入门教程 概述 本教程旨在为基于Nodejs npm生态圈的前端程序开发提供入门讲解. Nodejs是什么 Nodejs是一个高性能Ja ...
- 【Electron】Electron开发入门
Electron简介: Electron提供了丰富的本地(操作系统)的API,使你能够使用纯JavaScript来创建桌面应用程序,并且跨平台(win,mac,linux等各种PC端平台).与其它各种 ...
随机推荐
- huffman编码——原理与实现
哈夫曼算法原理 Wikipedia上面说的非常清楚了,这里我就不再赘述,直接贴过来了. 1952年, David A. Huffman提出了一个不同的算法,这个算法能够为不论什么的可能性提供出一个理想 ...
- 怎样将关系型数据表转换至hbase数据表
首先须要把关系型数据库的数据表的数据添加由 "纵向延伸",转变为HBase数据表的"横向延伸" 一.Hbase的存储结构 a) HBase以表(HTa ...
- Facebook的手游出海之道
对于不同的游戏公司,面临的同一个问题就是怎样让海外玩家能够一眼在App中发现你,成为你的新用户:不仅如此,怎样留住这些用户,让他们成为你游戏的忠实玩家也是让全部游戏开发商困扰的一个问题. w=580& ...
- [转] DAG算法在hadoop中的应用
http://jiezhu2007.iteye.com/blog/2041422 大学里面数据结构里面有专门的一章图论,可惜当年没有认真学习,现在不得不再次捡 起来.真是少壮不努力,老大徒伤悲呀!什么 ...
- 转 - markdown 简明语法
Markdown是一种极简的『标记语言』,将文本转为HTML,通常为我大码农所用.其不追求大而全,简洁至上,正所谓不求最贵,只求最好! 本文介绍Markdown基本语法,内容很少,一行语法一行示例,学 ...
- z-index优先级总结
因为显示器显示的图案是一个二维平面,拥有x轴和y轴来表示位置属性.为了表示三维立体的概念如显示元素的上下层的叠加顺序引入了z-index属性来表示z轴的区别,表示一个元素在叠加顺序上的上下立体关系. ...
- javascript !!的作用是把一个其他类型的变量转成的bool类型
!!的作用是把一个其他类型的变量转成的bool类型
- DNN模块开发之利器篇:七种武器
我们在进行DNN模块开发时经常需要调用Dotnetnuke.dll中的方法函数,模块开发用到DNN的方法函数会让你的开发更加得心应手,下面我们就来介绍一下. 1) PortalModuleBase ...
- mysql 数据库字符串替换
UPDATE `table_name` SET `field_name` = replace (`field_name`,'from_str','to_str') WHERE `field_name` ...
- C++ Primer 5th 第7章 类
类的基本思想是数据抽象和封装,定义类就是定义一个抽象数据类型. 类中的所有成员必须在类中声明,也即默认定义在类中的成员全部为声明,除非显式的定义成员函数的函数体.成员函数是在类中声明的,定义可以在类内 ...