nodejs入门开发与常用模块

  • npm:NodeJs包管理器
  • express:服务器端比较流行的MVC框架,处理服务请求,路由转发,逻辑处理
  • http://socket.io:实现服务端和客户端socket通信解决方案




正式开启JavaScript的后端开发之旅。

由于Node.js平台是在后端运行JavaScript代码,所以,必须首先在本机安装Node环境。输入 node -v 验证

输入 node ,此刻你将进入Node.js的交互环境。

在交互环境下,你可以输入任意JavaScript语句,
要退出Node.js环境,连按两次Ctrl+C。

为啥我们需要一个包管理工具呢?因为我们在Node.js上开发时,会用到很多别人写的JavaScript代码。如果我们要使用别人写的某个包,每次都根据名称搜索一下官方网站,下载代码,解压,再使用,非常繁琐。于是一个集中管理的工具应运而生:大家都把自己开发的模块打包后放到npm官网上,如果要使用,直接通过npm安装就可以直接用,不用管代码存在哪,应该从哪下载。

更重要的是,如果我们要使用模块A,而模块A又依赖于模块B,模块B又依赖于模块X和模块Y,npm可以根据依赖关系,把所有依赖的包都下载下来并管理起来。

npm已经在Node.js安装的时候顺带装好了。我们在命令提示符或者终端输入 npm -v


编辑 hello.js

'use strict';console.log('Hello, world.');
第一行总是写上 'use strict'; 是因为我们总是以严格模式运行JavaScript代码,避免各种潜在陷阱。
运行
node hello.js


每个文件都写上 'use strict'; 很麻烦。我们可以给Nodejs传递一个参数,让Node直接为所有js文件开启严格模式:
node --use_strict calc.js


在编写JavaScript代码的时候,完全可以一边在文本编辑器里写代码,一边开一个Node交互式命令窗口,在写代码的过程中, 把部分代码粘到命令行去验证 ,事半功倍!前提是得有个27'的超大显示器!


IDE开发调试工具Visual Studio Code 可以跨!平!台!


模块!

一个.js文件就称之为一个模块
相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。
模块的名字就是文件名

module.exports = greet;
把函数 greet 作为模块的输出暴露出去,这样其他模块就可以使用 greet 函数了。

'use strict' ; // 引入hello模块: var greet = require ( './hello' ); var s = 'Michael' ;greet(s); // Hello, Michael!

引入的模块作为 变量 保存在 greet 变量中,
greet 变量到底是什么东西?
其实变量 greet 就是用 module.exports = greet; 输出的 greet 函数
所以, main.js 就成功地引用了 hello.js 模块中定义的 greet() 函数,接下来就可以直接使用它了。

一个模块想要对外暴露变量(函数也是变量),可以用 module.exports = variable; ,一个模块要引用其他模块暴露的变量,用 var ref = require('module_name'); 就拿到了引用模块的变量。

引入的对象具体是什么,取决于引入模块输出的对象。


输出多个
module.exports = {
greet: greet,
hi: hi,
goodbye: goodbye
};
使用
const hello = require ( './hello' );
hello .greet(s);
hello.goodbye(s);


JavaScript有且仅有一个全局对象,在浏览器中,叫 window 对象。而在Node.js环境中,也有唯一的全局对象,但不叫 window ,而叫 global
这个对象的属性和方法也和浏览器环境的 window 不同。

进入Node.js交互环境,可以直接输入:
> global .console
试试

JavaScript程序是由事件驱动执行的单线程模型,Node.js也不例外。Node.js不断执行响应事件的JavaScript函数,直到没有任何响应事件的函数可以执行时,Node.js就退出了。


如果我们响应 exit 事件,就可以在程序即将退出时执行某个回调函数:
// 程序即将退出时的回调函数: process.on( 'exit' , function (code) { console.log( 'about to exit with code: ' + code);});



判断JavaScript执行环境
if ( typeof (window) === 'undefined' ) { console.log( 'node.js' );} else { console.log( 'browser' );}


文件系统

异步读文件
var fs = require ( 'fs' );fs.readFile( 'sample.txt' , 'utf-8' , function (err, data) { if (err) { console.log(err); } else { console.log(data); }});
当正常读取时, err 参数为 null data 参数为读取到的String。
当读取发生错误时, err 参数代表一个错误对象, data undefined

这也是Node.js标准的回调函数:第一个参数代表错误信息,第二个参数代表结果。后面我们还会经常编写这种回调函数。


读取一个图片文件
fs.readFile( 'sample.png' , function (err, data) { if (err) { console.log(err); } else { console.log(data); console.log(data.length + ' bytes' ); }});

当读取二进制文件时,不传入文件编码时,回调函数的 data 参数将返回一个 Buffer 对象。在Node.js中, Buffer 对象就是一个包含零个或任意个字节的数组(注意和Array不同)。

Buffer 对象可以和String作转换,例如,把一个 Buffer 对象转换成String:
// Buffer -> String var text = data.toString( 'utf-8' );console.log(text);
或者把一个String转换成 Buffer
// String -> Buffer var buf = Buffer.from(text, 'utf-8' );console.log(buf);

同步读文件
同步读取的函数和异步函数相比,多了一个 Sync 后缀,并且不接收回调函数,函数直接返回结果。
var data = fs.readFileSync( 'sample.txt' , 'utf-8' );console.log(data);
如果同步读取文件发生错误,则需要用 try...catch 捕获该错误:

try { var data = fs.readFileSync( 'sample.txt' , 'utf-8' ); console.log(data);} catch (err) { // 出错了 }

写文件
fs.writeFile

fs.stat(filepath, function (err, stats) { if (!err && stats.isFile()) { // 没有出错并且文件存在: console.log( '200 ' + request.url); // 发送200响应: response.writeHead( 200 ); // 将文件流导向response: fs.createReadStream(filepath). pipe (response); } else { // 出错了或者文件不存在: console.log( '404 ' + request.url); // 发送404响应: response.writeHead( 404 ); response.end( '404 Not Found' ); } });

由于 response 对象本身是一个 Writable Stream ,直接用 pipe() 方法就实现了自动读取文件内容并输出到HTTP响应。


stream流

在Node.js中,流也是一个对象,我们只需要响应流的事件就可以了: data 事件表示流的数据已经可以读取了, end 事件表示这个流已经到末尾了,没有数据可以读取了, error 事件表示出错了。
// 打开一个流: var rs = fs.createReadStream( 'sample.txt' , 'utf-8' );rs.on( 'data' , function (chunk) { console.log( 'DATA:' ) console.log(chunk);});rs.on( 'end' , function () { console.log( 'END' );});rs.on( 'error' , function (err) { console.log( 'ERROR: ' + err);});
要注意, data 事件可能会有多次,每次传递的 chunk 是流的一部分数据。


就像可以把两个水管串成一个更长的水管一样,两个流也可以串起来。一个 Readable 流和一个 Writable 流串起来后,所有的数据自动从 Readable 流进入 Writable 流,这种操作叫 pipe

Node.js中, Readable 流有一个 pipe() 方法,就是用来干这件事的。


HTTP模块

Node.js开发的目的就是为了用JavaScript编写Web服务器程序。
request 对象封装了HTTP请求,我们调用 request 对象的属性和方法就可以拿到所有HTTP请求的信息;
response 对象封装了HTTP响应,我们操作 response 对象的方法,就可以把HTTP响应返回给浏览器。

用Node.js实现一个HTTP服务器程序非常简单。
'use strict' ; // 导入http模块: var http = require ( 'http' ); // 创建http server,并传入回调函数: var server = http.createServer( function (request, response) { // 回调函数接收request和response对象, // 获得HTTP请求的method和url: console.log(request.method + ': ' + request.url); // 将HTTP响应200写入response, 同时设置Content-Type: text/html: response. writeHead ( 200 , { 'Content-Type' : 'text/html' }); // 将HTTP响应的HTML内容写入response: response.end( '<h1>Hello world!</h1>' );}); // 让服务器监听8080端口: server.listen( 8080 );console.log( 'Server is running at http://127.0.0.1:8080/' );
使用node ***.js执行即可




解析URL:
var url = require ( 'url' );console.log(url.parse( 'http://user:pass@host.com:8080/path/to/file?query=string#hash' ));
结果如下:
Url { protocol : 'http:' , slashes: true, auth: 'user:pass' , host: 'host.com:8080' , port: '8080' , hostname: 'host.com' , hash: '#hash' , search: '?query=string' , query: 'query=string' , pathname: '/path/to/ file ' , path: '/path/to/file?query=string' , href: 'http://user:pass@host.com:8080/path/to/file?query=string#hash' }

处理本地文件目录需要使用Node.js提供的 path 模块
var path = require ( 'path' ); // 解析当前目录: var workDir = path.resolve( '.' ); // '/Users/michael' // 组合完整的文件路径:当前目录+'pub'+'index.html': var filePath = path.join(workDir, 'pub' , 'index.html' ); // '/Users/michael/pub/index.html'



加密和哈希
Nodejs 用C/C++实现 这些算法后,通过cypto这个模块暴露为JavaScript接口,这样用起来方便,运行速度也快。

MD5是一种常用的哈希算法,用于给任意数据一个“签名”。这个签名通常用一个十六进制的字符串表示:
onst crypto = require ( 'crypto' ); const hash = crypto.createHash( 'md5' );//也可以用 sha1
// 可任意多次调用update(): hash.update( 'Hello, world!' );hash.update( 'Hello, nodejs!' );console.log(hash.digest( 'hex' )); // 7e1977739c748beac0c0fd14fd26a544

Hmac算法也是一种哈希算法
const crypto = require ( 'crypto' ); const hmac = crypto.createHmac( 'sha256' , 'secret-key' );hmac.update( 'Hello, world!' );hmac.update( 'Hello, nodejs!' );console.log(hmac.digest( 'hex' )); // 80f7e22570...


AES是一种常用的对称加密算法,加解密都用同一个密钥。
加密结果通常有两种表示方法:hex和base64


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值