Node.js 能做什么

正如 JavaScript 为客户端而生,Node.js 为网络而生。Node.js 能做的远不止开发一个网站那么简单,使用 Node.js,你可以轻松地开发:

  • 具有复杂逻辑的网站;
  • 基于社交网络的大规模 Web 应用;
  • Web Socket 服务器;
  • TCP/UDP 套接字应用程序;
  • 命令行工具;
  • 交互式终端程序;
  • 带有图形用户界面的本地应用程序;
  • 单元测试工具;
  • 客户端 JavaScript 编译器。

Node.js 内建了 HTTP 服务器支持,也就是说你可以轻而易举地实现一个网站和服务器的组合。这和 PHP、Perl 不一样,因为在使用 PHP 的时候,必须先搭建一个 Apache 之类的 HTTP 服务器,然后通过 HTTP 服务器的模块加载或 CGI 调用,才能将 PHP 脚本的执行结果呈现给用户。而当你使用 Node.js 时,不用额外搭建一个 HTTP 服务器,因为 Node.js 本身就内建了一个。这个服务器不仅可以用来调试代码,而且它本身就可以部署到产品环境,它的性能足以满足要求。

Node.js 还可以部署到非网络应用的环境下,比如一个命令行工具。Node.js 还可以调用 C/C++ 的代码,这样可以充分利用已有的诸多函数库,也可以将对性能要求非常高的部分用 C/C++ 来实现。

创建一个 HTTP 服务器

//app.js 

var http = require('http'); 

http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Node.js</h1>');
res.end('<p>Hello World</p>');
}).listen(3000);
console.log("HTTP server is listening at port 3000.");

EventEmitter 的用法:

//event.js 

var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter(); event.on('some_event', function() {
console.log('some_event occured.');
}); setTimeout(function() {
event.emit('some_event');
}, 1000);

运行这段代码,1秒后控制台输出了 some_event occured.。其原理是 event 对象注册了事件 some_event 的一个监听器,然后我们通过 setTimeout 在1000毫秒以后向 event 对象发送事件 some_event,此时会调用 some_event 的监听器。

Node.js调试工具

node-inspector

util.inherits 的用法,示例如下:

var util = require('util'); 

function Base() {
this.name = 'base';
this.base = 1991; this.sayHello = function() {
console.log('Hello ' + this.name);
};
} Base.prototype.showName = function() {
console.log(this.name); }; function Sub() {
this.name = 'sub';
} util.inherits(Sub, Base); var objBase = new Base();
objBase.showName();
objBase.sayHello();
console.log(objBase); var objSub = new Sub();
objSub.showName();
//objSub.sayHello();
console.log(objSub);

我们定义了一个基础对象 Base 和一个继承自 Base 的 Sub,Base 有三个在构造函数内定义的属性和一个原型中定义的函数,通过 util.inherits 实现继承。运行结果如下:

base
Hello base
{ name: 'base', base: 1991, sayHello: [Function] }
sub
{ name: 'sub' }

注意,Sub 仅仅继承了 Base 在原型中定义的函数,而构造函数内部创造的 base 属性和 sayHello 函数都没有被 Sub 继承。同时,在原型中定义的属性不会被 console.log 作为对象的属性输出。如果我们去掉 objSub.sayHello(); 这行的注释,将会看到:

node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^ TypeError: Object #<Sub> has no method 'sayHello'
at Object.<anonymous> (/home/byvoid/utilinherits.js:29:8)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Array.0 (module.js:479:10)
at EventEmitter._tickCallback (node.js:192:40)

fs 模块函数表

打开文件

fs.open(path,flags, [mode], [callback(err, fd)])

fs.openSync(path, flags, [mode])

**关闭文件 **

fs.close(fd, [callback(err)])

fs.closeSync(fd)

读取文件 (文件描\述符)

fs.read(fd,buffer,offset,length,position, [callback(err, bytesRead, buffer)])

fs.readSync(fd, buffer, offset, length, position)

写入文件 (文件描述符)

fs.write(fd,buffer,offset,length,position, [callback(err, bytesWritten, buffer)])

fs.writeSync(fd, buffer, offset, length, position)

**读取文件内容 **

fs.readFile(filename,[encoding],[callback(err, data)])

fs.readFileSync(filename, [encoding])

**写入文件内容 **

fs.writeFile(filename, data,[encoding], [callback(err)])

fs.writeFileSync(filename, data, [encoding])

删除文件

fs.unlink(path, [callback(err)])

fs.unlinkSync(path)

**创建目录 **

fs.mkdir(path, [mode], [callback(err)])

fs.mkdirSync(path, [mode])

删除目录

fs.rmdir(path, [callback(err)])

fs.rmdirSync(path)

**读取目录 **

fs.readdir(path, [callback(err, files)])

fs.readdirSync(path)

**获取真实路径 **

fs.realpath(path, [callback(err, resolvedPath)])

fs.realpathSync(path)

**更名 **

fs.rename(path1, path2, [callback(err)])

fs.renameSync(path1, path2)

**截断 **

fs.truncate(fd, len, [callback(err)])

fs.truncateSync(fd, len)

**更改所有权 **

fs.chown(path, uid, gid, [callback(err)])

fs.chownSync(path, uid, gid)

**更改所有权 (文件描述符) **

fs.fchown(fd, uid, gid, [callback(err)])

fs.fchownSync(fd, uid, gid)

更改所有权 (不解析符号链接)

fs.lchown(path, uid, gid, [callback(err)])

fs.lchownSync(path, uid, gid)

**更改权限 **

fs.chmod(path, mode, [callback(err)])

fs.chmodSync(path, mode)

更改权限 (文件描述符)

fs.fchmod(fd, mode, [callback(err)])

fs.fchmodSync(fd, mode)

更改权限 (不解析符号链接)

fs.lchmod(path, mode, [callback(err)])

fs.lchmodSync(path, mode)

获取文件信息

fs.stat(path, [callback(err, stats)])

fs.statSync(path)

**获取文件信息 (文件描述符) **

fs.fstat(fd, [callback(err, stats)])

fs.fstatSync(fd)

获取文件信息 (不解析符号链接)

fs.lstat(path, [callback(err, stats)])

fs.lstatSync(path)

**创建硬链接 **

fs.link(srcpath, dstpath, [callback(err)])

fs.linkSync(srcpath, dstpath)

**创建符号链接 **

fs.symlink(linkdata, path, [type], [callback(err)])

fs.symlinkSync(linkdata, path, [type])

读取链接

fs.readlink(path, [callback(err, linkString)])

fs.readlinkSync(path)

修改文件时间戳

fs.utimes(path, atime, mtime, [callback (err)])

fs.utimesSync(path, atime, mtime)

修改文件时间戳(文件描述符)

fs.futimes(fd, atime, mtime, [callback (err)])

fs.futimesSync(fd, atime, mtime)

**同步磁盘缓存 **

fs.fsync(fd, [callback(err)])

fs.fsyncSync(fd)


获取 GET 请求内容

//httpserverrequestget.js 

var http = require('http');
var url = require('url');
var util = require('util'); http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(util.inspect(url.parse(req.url, true)));
}).listen(3000);

在浏览器中访问 http://127.0.0.1:3000/username=byvoid&email=byvoid@byvoid.com,我们可以看到浏览器返回的结果:

{ search: '?name=byvoid&email=byvoid@byvoid.com',
query: { name: 'byvoid', email: 'byvoid@byvoid.com' },
pathname: '/user',
path: '/user?name=byvoid&email=byvoid@byvoid.com',
href: '/user?name=byvoid&email=byvoid@byvoid.com' }

通过 url.parse原始的 path 被解析为一个对象,其中 query 就是我们所谓的 GET 请求的内容,而路径则是 pathname。

获取 POST 请求内容

//httpserverrequestpost.js 

var http = require('http');
var querystring = require('querystring');
var util = require('util'); http.createServer(function(req, res) {
var post = ''; req.on('data', function(chunk) {
post += chunk;
}); req.on('end', function() {
post = querystring.parse(post);
res.end(util.inspect(post));
}); }).listen(3000);

上面代码并没有在请求响应函数中向客户端返回信息,而是定义了一个 post 变量,用于在闭包中暂存请求体的信息。 通过 req 的 data 事件监听函数, 每当接受到请求体的数据,就累加到 post 变量中。在 end 事件触发后,通过 querystring.parse 将 post 解析为真正的 POST 请求格式,然后向客户端返回。

使用 Node.js进行 Web 开发

1.安装 Express

npm install -g express

2.建立工程

express -t ejs microblog 

cd microblog && npm install

node开发指南的更多相关文章

  1. Node.js开发指南中的例子(mysql版)

    工作原因需要用到nodejs,于是找到了<node.js开发指南>这本书来看看,作者BYVoid 为清华大学计算机系的高材生,年纪竟比我还小一两岁,中华地广物博真是人才辈出,佩服. 言归正 ...

  2. 学习Nodejs:《Node.js开发指南》微博项目express2迁移至express4过程中填的坑

    <Node.js开发指南>项目地址https://github.com/BYVoid/microblog好不容易找到的基础版教程,但书中是基于express2的,而现在用的是express ...

  3. 《node.js开发指南》partial is not defined的解决方案

    由于ejs的升级,<node.js开发指南>中使用的 partial 函数已经摒弃,使用foreach,include代替 原来的代码是: <%- partial('listitem ...

  4. nodejs开发指南读后感

    nodejs开发指南读后感 阅读目录 使用nodejs创建http服务器; supervisor的使用及nodejs常见的调式代码命令了解; 了解Node核心模块; ejs模板引擎 Express 理 ...

  5. AngularJS开发指南16:AngularJS构建大型Web应用详解

    AngularJS是由Google创建的一种JS框架,使用它可以扩展应用程序中的HTML功能,从而在web应用程序中使用HTML声明动态内容.在该团队工作的软件工程师Brian Ford近日撰写了一篇 ...

  6. Spark开发指南

    原文链接http://www.sxt.cn/info-2730-u-756.html 目录 Spark开发指南 简介 接入Spark Java 初始化Spark Java 弹性分布式数据集 并行集合 ...

  7. [翻译]现代java开发指南 第二部分

    现代java开发指南 第二部分 第二部分:部署.监控 & 管理,性能分析和基准测试 第一部分,第二部分 =================== 欢迎来到现代 Java 开发指南第二部分.在第一 ...

  8. [翻译]现代java开发指南 第一部分

    现代java开发指南 第一部分 第一部分:Java已不是你父亲那一代的样子 第一部分,第二部分 =================== 与历史上任何其他的语言相比,这里要排除c语言和cobol语言,现 ...

  9. nodejs 开发指南 书中小项目 代码

    最近 在学习node.js 先看了下语法 ,然后就看这个开发指南感觉书还是很有用,但是代码太旧了,网上也没有最新的,所以就自己查着前人的痕迹和自己修改,现在可以跑了. https://github.c ...

随机推荐

  1. 创建XMLHttpRequest对象

    创建XMLHttpRequest对象 XMLHttpRequest对象: 用于在后台与服务器交换数据,可以在不重新加载整个页面的情况下,对页面的部分内容进行更新. 创建XMLHttpRequest对象 ...

  2. Tips collection of iOS development

    <转>UITableView当数据很少的时候,去掉多余的cell分割线   在tableView初始化的时候 UIView *v = [[UIViewalloc] initWithFram ...

  3. Kanzi编程基础1 - 定时器Timer

    Kanzi虽然发生了比较多的版本更迭,api也发生了很多变化,但定时器的头文件一直都在一个地方:#include "user/include/user/ui/message/kzu_mess ...

  4. c# 无法加载 DLL xxxxxxxx找不到指定的模块。 (异常来自HRESULT:0x8007007E)。的一个解决方法

    最近在做一个程序,想把某些功能用C++写成DLL供C#调用.但是无法如何都无法调用,提示"无法加载 DLL xxxxxxxx找不到指定的模块. (异常来自HRESULT:0x8007007E ...

  5. 淘宝网触屏版 - 学习笔记(1 - 关于meta)

    注:本文是学习笔记,并不是教程,所以会有很多我不理解或猜测的问题,也会有不尽详实之处,望见谅. <meta charset="utf-8"> <meta cont ...

  6. 程序设计入门——C语言 第7周编程练习 2 鞍点(5分)(5分)

    2 鞍点(5分) 题目内容: 给定一个n*n矩阵A.矩阵A的鞍点是一个位置(i,j),在该位置上的元素是第i行上的最大数,第j列上的最小数.一个矩阵A也可能没有鞍点. 你的任务是找出A的鞍点. 输入格 ...

  7. 常见的js 里对数字进行处理的函数方法集合

    常见的对小数值舍入为整数的几个方法:Math.ceil().Math.floor()和Math.round(). 这三个方法分别遵循下列舍入规则: Math.ceil()执行向上舍入,即它总是将数值向 ...

  8. Linux-ubuntu指令使用积累(长期更新)

    alias cat cd cp ls mkdir mv rm sudo tar chmod       1. sudo 系统管理指令.放在其它指令之前使用,允许普通用户在root权限下执行部分或者全部 ...

  9. jquery ajax 方法及各参数详解

    1.$.ajax() 只有一个参数:参数 key/value 对象,包含各配置及回调函数信息. 参数列表: 参数名 类型 描述 url String (默认: 当前页地址) 发送请求的地址. type ...

  10. TAP/TUN摘要

    TUN适用于IP帧.Tap适用于以太网帧.TAP摸拟一个以太网设备(以arp广播MAC识别),它操作第二层数据包如以太网数据帧.TUN模拟了网络层ip设备(以点对点的方式,使用ip标识),操作第三层数 ...