初步认识Node.js

CommonJS规范

每一个js文件都是一个模块,js文件的名字就是模块的名字。每个模块内部使用的变量名和函数名互不冲突。

一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable,还可以exports.variable=variable;如果要输出一个键值对象{},可以利用exports这个已存在的空对象{},并继续在上面添加新的键值;如果要输出一个函数或数组,必须直接对module.exports对象赋值。

一个模块要引用其他模块暴露的变量,用var ref = require('module_name');就拿到了引用模块的变量。在引用模块时要把相对路径写对,直接写模块名会依次在内置模块、全局模块和当前模块下查找。

全局对象

node.js的全局对象global相当于浏览器环境中的全局对象window

根据全局对象判断JavaScript的执行环境;

if(typeof(window)==='undefined'){
    console.log('node.js');
}else{
    console.log('browser');
}

node.js的process对象

process=global.process,代表当前Node.js进程;

process.nextTick(function(){});nextTick中的函数不会立刻执行,而是要等到下一次事件循环;

process.on('exit',function(){});在程序即将退出时执行该回调函数。

内置模块

fs模块

文件系统模块,负责读写文件。fs模块同时提供了异步和同步的方法。

异步方法

因为JavaScript的单线程模型,执行IO操作时,JavaScript代码无需等待,而是传入回调函数后,继续执行后续JavaScript代码。

$.getJSON('http://example.com/ajax',function(data){
    console.log('IO结果返回执行...');
});
console.log('不等待IO结果直接执行后续代码...');

同步方法

同步方法:同步的IO操作则需要等待函数返回。

var data=getJSONSync('http://example.com/ajax');

同步操作的好处是代码简单,缺点是程序将等待IO操作,在等待时间内,无法响应其它任何事件。而异步读取不用等待IO操作,但代码较麻烦。

异步与同步

由于Node环境执行的JavaScript代码是服务器端代码,所以,绝大部分需要在服务器运行期反复执行业务逻辑的代码,必须使用异步代码,否则,同步代码在执行时期,服务器将停止响应,因为JavaScript只有一个执行线程。

服务器启动时如果需要读取配置文件,或者结束时需要写入到状态文件时,可以使用同步代码,因为这些代码只在启动和结束时执行一次,不影响服务器正常运行时的异步执行。

异步读文件

'use strict';
var fs=require('fs');
fs.readFile('sample.txt','utf-8',function(err,data){
    if(err){
        console.log(err);
    }else{
        console.log(data);
    }
});
console.log('start process');

sample.txt文件必须在当前目录,utf-8为文件的编码;

node.js标准的回调函数,第一个参数代表错误信息,第二个参数代表结果;

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

Buffer对象与String之间的转换:

Buffer->String:var text=data.toString('utf-8');
String->Buffer:var buf=Buffer.from(text,'utf-8');

同步读文件

'use strict';
var fs=require('fs');
try{
    var data=fs.readFileSync('sample.txt','utf-8');
    console.log(data);
}catch(err){
    console.log(err);
}
console.log('start');

异步写文件

'use strict'
var fs=require('fs');
var data='write data into file';
fs.writeFile('sample.txt',data,function(err){
    if(err){
        console.log(err);
    }else{
        console.log('done!');
    }
});

writeFile()的参数依次为文件名、数据和回调函数。如果传入的数据是String,默认按UTF-8编码写入文本文件,如果传入的参数是Buffer,则写入的是二进制文件。回调函数由于只关心成功与否,因此只需要一个err参数。

同步写文件

'use strict';
var fs=require('fs');
var data='write date into file';
fs.writeFileSync('output.txt',data);

获取文件大小、创建时间等信息

fs.stat()返回一个Stat对象,能告诉我们文件或目录的详细信息。

//异步
'use strict';
var fs=require('fs');
fs.stat('sample.txt',function(err,stat){
    if(err){
        console.log(err);
    }else{
        console.log('isFile:'+stat.isFile());
        console.log('isDirectory:'+stat.isDirectory());
        if(stat.isFile()){
            console.log('size:'+stat.size);
            console.log('birth time:'+stat.birthtime);
            console.log('modified time:'+stat.mtime);
        }
    }
});
//同步
'use strict';
var fs=require('fs');
try{
    var stat=fs.statSync('sample.txt');
    console.log('isFile:'+stat.isFile());
    console.log('isDirectory:'+stat.isDirectory());
    if(stat.isFile()){
        console.log('size:'+stat.size);
        console.log('birth time:'+stat.birthtime);
        console.log('modified time:'+stat.mtime);
    }
}catch(err){
    console.log(err);
}

流读写文件

所有能读取数据的流都继承自stream.Readable;所有能写入数据的流都继承自stream.Writable;

//读操作
'use strict';
var fs = require('fs');
var rs = fs.createReadStream('sample.txt', 'utf-8')
rs.on('data', function (chunk) {//data事件表示流的数据已经可以读取。
    console.log('DATA:');
    console.log(chunk);
});
rs.on('end', function () {//end事件表示这个流已经到了末尾,没有数据可读。
    console.log('END');
});
rs.on('error', function (err) {//error表示事件出错。
    console.log('ERROR: ' + err);
});
//写操作
var ws=fs.createWriteStream('sample.txt','utf-8');
ws.write('write data into file with stream');
ws.end;

pipe

一个Readable流和一个Writable流串起来后,所有数据自动从Readable流进入Writeable流,这种操作叫pipe。

默认情况下,当Readable流的数据读取完毕,end事件触发后,将自动关闭Writable流。如果我们不希望自动关闭Writable流,需要传入参数

readable.pipe(writable,{end:false});

Node.js实现HTTP服务器程序

处理TCP连接,解析HTTP都由http模块完成了,HTTP请求和HTTP响应都分别封装在http模块中的request对象和response对象中。

//简单的HTTP服务程序
'use strict';
var http=require('http');
var server=http.createServer(function(request,response){
    console.log(request.method+":"+request.url); 
    response.writeHead(200,{'Content-Type':'text/html'});
    response.end('<h1>hello world</h1>');
});
server.listen(8080);
console.log('Server is running at http://127.0.0.1:8080/');
Node.js实现文件服务器

解析URL需要用到Node.js提供的url模块,通过parse()将一个字符串解析为一个Url对象;

处理本地文件目录需要使用Node.js提供的path模块,使用path模块可以正确处理操作系统相关的文件路径;

//简单的文件服务器
'use strict';
var 
    fs=require('fs'),
    url=require('url'),
    path=require('path'),
    http=require('http');
// 从命令行参数获取root目录,默认是当前目录
var root = path.resolve(process.argv[2] || '.');
console.log(process.argv[2]);
console.log('Static root dir: ' + root);
var server=http.createServer(function(request,response){
    var pathname = url.parse(request.url).pathname;
    var filepath = path.join(root, pathname);
    fs.stat(filepath, function (err, stats) {
        if (!err && stats.isFile()) {
            console.log('200 ' + request.url);
            response.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
            //response.write('<meta charset="utf-8"/> ');
            fs.createReadStream(filepath).pipe(response);//由于response对象本身是一个Writable Stream,直接用pipe()方法就实现了自动读取文件内容并输出到HTTP响应
        } else {
            console.log('404 ' + request.url);
            response.writeHead(404);
            response.end('404 Not Found');
        }
    });
});
server.listen(8080);
console.log('Server is running at http://127.0.0.1:8080/');
node.js的加密模块crypto

crypto模块的目的是为了提供通用的加密和哈希算法,Nodejs用C/C++实现这些算法后,通过cypto这个模块暴露为JavaScript接口。

MD5和SHA1

const crypto=require('crypto');
const hash=crypto.createHash('md5');//098f6bcd4621d373cade4e832627b4f6
//const hash=crypto.createHash('sha1');//a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
hash.update('test');//update()方法默认字符串编码为UTF-8,也可以传入Buffer
console.log(hash.digest('hex'));//以十六进制的方式输出
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值