一:网络操作
1:简介
通过node.js可以编写服务端的程序协助前端和测试,还需要http协议和socket协议
var http = require(‘http’);
http.createServer(function(request,response){
response.writeHead(200,{‘Content-Type’:’text-plain’});
response.end(‘hello’)
}).listen(8124)
2:简易的api
(1)http 模块
使用服务端,创建http服务器
使用客户端,发起http客户端请求
先用createServer创建一个服务器,调用listen监听端口
http请求本质是一个数据流,由请求头headers和请求体body
//请求头
POST / HTTP/1.1
User-Agent: curl/7.26.0
Host: localhost
Accept: /
Content-Length: 11
Content-Type: application/x-www-form-urlencoded
//请求体
Hello World
http.createServer(function(request,response){
var body = [];
console.log(request.method);
console.log(request.headers);
request.on(‘data’,function(chunk){
body.push(chunk);
})
request.on(‘end’,function(){
body = Buffer.concat(body);
console.log(body.toString())
})
}).listen(80);
(2)https 模块
https 和 http 区别在于https模块需要额外的ssl证书
在服务器端,创建一个https服务器
var options = {
key:fs.readFileSync(‘./ssl/default.key’),
cert:fs.readFileSync(‘./ssl/default/cer)
};
var server = https.createServer(option,function(request,response){
})
可以看到,与创建HTTP服务器相比,多了一个options对象,通过key和cert字段指定了HTTPS服务器使用的私钥和公钥。
(3)url 模块
处理http模块 url模块使用率超高
url.parse(‘http://user:pass@host.com:8080/p/a/t/h?query=string#hash‘);
/* =>
{ protocol: ‘http:’,
auth: ‘user:pass’,
host: ‘host.com:8080’,
port: ‘8080’,
hostname: ‘host.com’,
hash: ‘#hash’,
search: ‘?query=string’,
query: ‘query=string’,
pathname: ‘/p/a/t/h’,
path: ‘/p/a/t/h?query=string’,
href: ‘http://user:pass@host.com:8080/p/a/t/h?query=string#hash’ }
*/
(4)querystring模块
用于实现url参数字符串和参数对象的转换
(5)zlib 模块
实现数据压缩和解压功能
var options = {
hostname: ‘www.example.com’,
port: 80,
path: ‘/’,
method: ‘GET’,
headers: {
‘Accept-Encoding’: ‘gzip, deflate’
}
}
http.request(options,function(response){
var body = [];
response.on(‘data’,function(chunk){
body.push(chunk)
})
response.on(‘end’,function(){
body = Buffer.concat(body);
if(response.headers[‘content-encoding’] === ‘gzip’){
zlib.gunzip(body,function(err,data){
console.log(data.toString());
})
}else{
console.log(data.toString())
}
})
}).end();
(6)net模块
用于创建Socket服务器和客户端。
二:进程管理
1:简介
node.js调用终端命令简化目录拷贝,感知和控制自身的运行状态,创建子进程协调工作,node.js可以把多个程序组合,其中充当浇水和调度器的作用
代码
var child_process = require(‘child_process’);
var util = require(‘util’);
function copy(source,target,callback){
child_process.exec(
util.format(‘cp -r %s/* %s’, source, target), callback);
)
}
copy(‘a’,’b’,function(err){
})
从以上代码中可以看到,子进程是异步运行的,通过回调函数返回执行结果。
2:简单的api与模块
(1)process
任何进程都有启动程序使用的命令参数,有输入输出,运行权限,运行环境和运行状态。
node.js通过process对象感知和控制node自身进程,process不是内置模块,全局对象,任何地方都能使用
(2)child_process
使用child_process模块可以创建和控制子进程,模块中api最核心的是.spawn,其余api都是对他的封装,算是一种语法糖
(3)cluster
cluster模块是对child_process模块的进一步封装,与用于解决node web服务器中无法利用多核cup,该模块可以简化多进程服务器程序开放,让每个核进行一个工作进程,统一通过驻进程监听端口和分发请求。
(4)事例
1.如何获得命令行参数
node.js中通过process.argv获得命令行参数,node执行程序路径和主模块占据了argv[0],argv[1],两个文字,从第一个命令行参数从argv[2]开始
function main(argv){
}
main(process.argv.slice(2));
2.如何退出程序
程序完成退出,退出状态码的0.如果我们在代码中捕获了异常,然后退出,状态码设置为指定数字,比如1;
try{
}catch(err){
process.exit(1);
}
3.如何控制输入输出
node.js标准输出流(stdin),一个标准输出流(stdout),一个标准错误流(stderr)分别对应process.stdin,process.stdout,process.stderr.第一个只读数据流,后面为只写数据流
function log(){
process.stdout.write(
util.format.apply(util,arguments)+’\n’
)
}
4.如何降权
http.createServer(callback).listen(80, function () {
var env = process.env,
uid = parseInt(env[‘SUDO_UID’] || process.getuid(), 10),
gid = parseInt(env[‘SUDO_GID’] || process.getgid(), 10);
process.setgid(gid);
process.setuid(uid);
});
5:如何创建子进程
例子
var child = child_process.spawn(‘node’, [ ‘xxx.js’ ]);
child.stdout.on(‘data’, function (data) {
console.log(‘stdout: ’ + data);
});
child.stderr.on(‘data’, function (data) {
console.log(‘stderr: ’ + data);
});
child.on(‘close’, function (code) {
console.log(‘child process exited with code ’ + code);
});
三:异步回调
node.js最优势的地方-事件机制和异步IO;
(1)回调
异步编程依托就是回调.
先看下面代码
function heavyCompute(n,callback){
var count = 0,
i,j;
for(i = n;i>0;–j){
for(j = n;j>0;–j){
count += 1;
}
}
callback(count);
}
heavyCompute(10000,function(count){
console.log(count)
});
console.log(‘hello’);
可以看到,以上代码中的回调函数仍然先于后续代码执行。JS本身是单线程运行的,不可能在一段代码还未结束运行时去运行别的代码,因此也就不存在异步执行的概念。但是,如果某个函数做的事情是创建一个别的线程或进程,并与JS主线程并行地做一些事情,并在事情做完后通知JS主线程,那情况又不一样了。我们接着看看以下代码。
setTimeout(function(){
console.log(‘World’)
},1000);
console.log(‘hello’);
可以看到,本来应该在1秒后被调用的回调函数因为JS主线程忙于运行其它代码,实际执行时间被大幅延迟。
ps:
什么是语法糖
语法糖就是为了避免coder出现错误并提高效率的语法层面的一种优雅的解决方案。
Polyfill:一段代码(或者插件),提供了那些开发者们希望浏览器原生提供支持的功能。