这篇文章主要为大家展示了“nodejs有什么作用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“nodejs有什么作用”这篇文章吧。
一、概览
1、html可以在浏览器直接打开运行,是因为浏览器是html文件的解析器
而js文件不能在浏览器直接运行,是因为浏览器不支持解析js文件,需要有一个解析器来解析js文件
可以下载安装nodejs解析器,并且里面自带了npm,通过node.exe可以直接运行js文件,是通过命令行的形式运行的
要运行某个js文件,直接node + 要运行的js文件名称或者直接是js代码,按回车即可
js操作的是浏览器,node操作的是电脑系统、文件等等
2、编辑器也可以直接运行,推荐使用webstorm
3、在Ecmascript部分,node和js其实是一样的,比如数据类型的定义、语法结构、内置对象
在js中的顶层对象:window
在node中的顶层对象:global,没有window这个概念
二、模块
es6通过import export来进行模块化
nodejs通过require来进行模块化
html通过script标签来引入js文件
1、在nodeJs里面,一个js文件就是一个模块,每个模块都有自己的作用域,
我们使用var声明的变量,不是全局的,而是属于当前模块下的
比如:1.js
var a = 100;
console.log(a); //100
console.log(global.a); //undefined ,不是全局下面的变量
global.a = 200;
console.log(a); //100 仍然是开始定义的100
console.log(global.a); //这时候才是200
2、filename:表示当前文件的绝对路径
dirname:表示当前文件所在目录的绝对路径
它们并非全局的,而是模块作用域下的
所以global.filename是访问不到的,返回undefined
console.log(filename); //E:\webstorm文件夹\index.js
console.log(__dirname); //E:\webstorm文件夹
3、模块路径
require(); //可以是绝对路径、相对路径
不能直接是require("1.js")这种不带./的,这种加载方式,会加载node中的核心模块,或者是node_modules里面的慕课
4、查找文件:
首先按照加载的模块的文件名进行查找;
如果没有找到,则会在模块文件名称后面自动加上.js的后缀,然后进行查找;
如果还没有找到,则会在模块文件名称后面自动加上.json的后缀,然后进行查找;
如果还没有找到,则会在模块文件名称后面自动加上.node的后缀,然后进行查找;
如果还没有找到,就会报错。
5、
在一个模块中,通过var定义的变量,其作用域范围是当前模块,外部不能够直接访问到;
如果我们想一个模块能够访问另一个模块中定义的变量,可以通过:
把变量作为global对象的一个属性(不推荐)
global.a = 100;
使用模块对象 module,这个对象不是全局的,而是每个模块下的对象
模块对象 module用于:保存提供和当前模块有关的一些信息,下面有很多属性:
exports:{}; //module的子对象,通过这个对象可以把一个模块中的局部变量暴露出去,供外部访问
因为exports也是一个对象,所以暴露变量出去之前,先声明一个key值,value值就是这个局部变量
var a = 100; module.exports.name = a; require(); //返回值就是module.exports对象
6、在模块作用域下,还有一个内置的模块对象,exports,它其实就是module.exports
所以:
module.exports.name = a; 可以写成 exports.name = a;
【注意】:不要这样操作
module.exports = [1,2,3]
也不要:exports = [1,2,3],只是追加属性,不要修改
三、global对象 全局对象
局部:
filename
dirname
全局:
日期对象 var d = new Date()
数组 var arr = new Array(1,2,3)
定时器
三-1、process对象(进程对象)——全局对象
process === global.process //true
可以在任何地方都能访问到,通过这个对象提供的属性和方法,使我们可以对当前运行的程序的进程进行访问和控制
1、process.argv
console.log(process.argv); // [ 'D:\Program Files\nodejs\node.exe', 'E:\webstorm文件夹\2.js' ]
第一个是解析器,第二个是js文件
如果带上参数,那么返回的数组里面就会包含你运行时带入的参数
举例: node process.argv a=1 // [ 'D:\Program Files\nodejs\node.exe', 'E:\webstorm文件夹\2.js','a=1' ]
2、process.execPath
开启当前进程的这个可执行文件的绝对路径
3、env
返回用户环境信息
4、version
返回node版本信息
5、versions
返回node以及node依赖包版本信息
6、pid
返回当前进程的pid 进程是node.exe
7、title
返回当前进程的显示名称(Getters/Setters)
8、arch
返回当前CPU处理器架构 arm/ia32/x64
9、platform
返回当前操作平台
10、cwd()
返回当前进程的工作目录
11、chdir(directory)
改变当前进程的工作目录
12、memoryUsage()
返回node进程的内存使用情况,单位是byte
12、exit(code)
退出
13、kill(pid)
向进程发送信息
14、IO
a、stdin、stdout:标准输入输出流(IO)
标准输入设备:向计算机输入数据和信息的设备,是计算机与用户或其他设备通信的桥梁。
例如:鼠标、键盘、摄像头等等
标准输出设备:是计算机硬件系统的终端设备,把计算机数据或信息以数字、字符、图像、声音等形式表现出来。例如:显示器、打印等等
stdin、stdout提供了操作输入数据和输出数据的方法,我们也通常称为IO操作
stdin:标准输入流
stdout:标准输出流
console.log(...) === process.stdout.write(...);
b、默认情况下,输入流是关闭的,要监听处理输入流数据,首先要开启输入流
//开启 process.stdin.resume(); 监听用户的输入数据,输入完成按下回车 process.stdin.on('data',function(chunk){ console.log('用户输入了:'+chunk); })
会一直监听,用户输入完成按下回车显示数据,再按下仍然会显示第二次输入的数据
四、Buffer类:类似数组
1、定义:一个用于更好的操作二进制数据的类
我们在操作文件或者网络数据的时候,其实操作的就是二进制数据流;Node为我们提供了一个更加方便的去操作这种数据流的类Buffer,他是一个全局的类,global.Buffer === buffer
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
Buffer.alloc(size); 创建一个Buffer对象,并且为这个对象分配一个空间大小,大小是size的8位字节;当我们为一个buffer对象分配了一个空间大小以后,其长度是固定的,不能更改。也就是后续不能再增加内容了
<Buffer 72 75 6e 6f 6f 62> //控制台显示的是16进制的
Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖),声明并赋值
Buffer.from(string[, encoding]): 返回一个被 string 的值初始化的新的 Buffer 实例,encoding默认是utf8
let bf2 = Buffer.from('miaov'); //bf2.length 5 返回的是字节数,不是字符串长度
let bf3 = Buffer.from('妙味'); //bf3.length 6 一个汉字占据3个字节
2、Buffer类方法
bf.length; //buffer的字节长度
bf[ index ]; //获取或者设置在index索引位置的8位字节内容
bf.write(string , [offset] , [length] , [encoding]); //根据参数offset偏移量和指定的encoding编码方式,将参数string写入数据写入buffer
bf.toString( [encoding],[start],[end] ); //根据encoding返回一个解码的string类型
bf.toJSON(); //返回一个JSON表示的Buffer实例,JSON.stringify将会默认调用来字符串序列化这个Buffer实例
bf.slice( [start],[end] ); //返回一个新的buffer,这个buffer将会和老的buffer引用相同的内存地址;
注意:修改这个新的buffer实例slice切片,也会改变原来的buffer
bf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
let bf2 = Buffer.from('miaov'); console.log(bf2); //<Buffer 6d 69 61 6f 76> //十六进制 console.log(bf2.toString()); //'miaov' for (let i=0;i<bf2.length;i++){ //m的十六进制是6d;十进制是109;二进制是0110 1101 console.log(bf2[i]); //109 105 97 111 118 十进制 console.log(String.fromCharCode(bf2[i])) // m i a o v 图形字符 } let bf = Buffer.alloc(5); let str = 'miaov'; //bf.write(str); //console.log(bf); //<Buffer 6d 69 61 6f 76> // bf.write(str,1); // console.log(bf); //从buffer第1位开始写入,第0位用00补上,<Buffer 00 6d 69 61 6f> bf.write(str,1,3); console.log(bf); //只写入三位,其他位用00补上,<Buffer 00 6d 69 61 00> console.log(bf.toJSON()); //{ type: 'Buffer', data: [ 0, 109, 105, 97, 0 ] }
3、Buffer中的静态方法(又叫类方法,即不需要实例化即可使用的方法)
Buffer.isEncoding(encoding):如果给定的编码encoding是有效的,返回true;否则返回false
Buffer.isBuffer(obj); 测试这个obj是否是一个Buffer
Buffer.byteLength(string,[encoding]):将会返回这个字符串的真实byte字节长度。encoding默认编码是utf8
let str1 = 'json'; console.log(str1.length); //4 字符长度 console.log(Buffer.byteLength(str1)); //4 字节长度
Buffer.concat(list,[totalLength]):返回一个保存着将传入Buffer数组中所有buffer对象拼接在一起的buffer对象
list是buffer对象,返回值是多个buffer对象拼接成的一个buffer对象
totalLength是拼接后的字节长度,不传是计算后的所有的字节长度,(建议预先设置,节省计算时间)
五、文件系统模块 File System
1、该模块是核心模块,需要使用require导入后使用:let fs = require('fs');
2、该模块提供了操作文件的一些API
异步的打开一个文件:
fs.open(path,flags,[mode],callback)
path:要打开文件的路径;
flags:打开文件的方式:读/写
mode:设置文件的模式:读/写/执行
callback:回调函数,接受2个参数:err、fd
err:文件打开失败的错误保存在err里面,如果成功err为null
fd:被打开文件的标识,和定时器类似,用于后续要操作文件的标识,即后续如果要操作某个打开的文件,把这个文件标识传到后续操作的某些方法里面去,即可知道操作的是当前文件
fs.open()的同步版:
fs.openSync(path,flags,[mode])
从指定的文档标识符fd读取文件数据
fs.read(fd,buffer,offset,length,position)
fd:通过open方法成功打开一个文件返回的编号
buffer:buffer对象,用于存储打开文件内部的信息
offset:偏移量,数据从buffer对象里面的第几位开始存储,起始是0
length: 读取的内容长度
position:从文件的第几位开始读取,默认是0,即从头开始
callback:接受三个参数,err错误信息、length返回的新的buffer对象的长度;newBf:返回的新的buffer对象
fs.read的同步版本,返回bytesRead的个数
fs.readSync(fd,buffer,offset,length,position,callback)
*通过文件标识fd,向指定的文件中写入buffer
fs.write(fd,buffer,offset,length,[position],callback)
同步版本:fs.writeSync(fd,buffer,offset,length,[position])
fd:通过open方法成功打开一个文件返回的编号
buffer:要写入到文件的数据
offset:从buffer对象中第几位开始写入数据,默认是0
length: 要写入的buffer数据的长度
position:向指定的文件的第几位开始写入buffer数据,默认是0,即从头开始写入数据,如果开头已经有数据,那么新的数据会覆盖原始数据
callback:接受三个参数,err错误信息、length写入数据的buffer对象的长度;newBf:写入数据的buffer对象
*通过文件标识fd,把data写入到文档中,如果data不是buffer对象的实例,则会把值强制转换成为一个字符串
fs.write(fd,data,[position],[encoding],callback)
同步版本:fs.writeSync(fd,data,[position],[encoding])
data:直接是一个字符串,此时不再从第几位写入了,而是全部写入到文件里,所以没有offset参数
关闭一个打开的文件
fs.close(fd,callback)
同步版本:fs.closeSync(fd)
六、更好用的文件系统方法
1、fs.writeFile(filename,data,[options],callback)
异步的将数据写入一个文件,如果文件不存在就新建,如果文件原先存在,则会被替换;data可以是一个string,也可以是一个原生buffer
同步版本:fs.writeFileSync(filename,data,[options])
2、fs.appendFile(filename,data,[options],callback)
异步的将数据添加到一个文件的尾部,如果文件不存在就新建,如果文件原先存在,则会将数据追加到文件的尾部;data可以是一个string,也可以是一个原生buffer
同步版本:fs.appendFileSync(filename,data,[options])
3、fs.readFile(filename,[options],callabck)
异步读取一个文件的全部内容
同步版本:fs.readFileSync(filename,[options])
4、fs.exists(path,callback)
检查指定路径的文件或者目录是否存在
同步版本:fs.existsSync(path)
5、fs.unlink(path,callback)
删除一个文件
同步版本:fs.unlink(path)
let fs = require('fs'); let filename = '2.txt'; //异步 if(fs.exists(filename,(err)=>{ if(!err){ fs.writeFile(filename,'hello',(err)=>{ if(err){ console.log("文件创建失败") }else{ console.log("文件创建成功") } }) }else{ fs.appendFile(filename,'-world',(err)=>{ if(err){ console.log('文件追加失败') }else{ console.log('文件追加成功') } }) } })); //同步 if(!fs.existsSync(filename)){ console.log('文件创建成功'); fs.writeFileSync(filename,'hello') }else{ console.log('文件追加成功'); fs.appendFileSync(filename,'-world') }
6、fs.rename(oldPath,newPath,callback)
重命名
同步版本:fs.renameSync(oldPath,newPath)
7、fs.stat(path,callback)
读取文件信息的状态,不是文件内部的内容,返回值是一个json,包括文件类型、文件日期、文件大小等等
mode=33206表示该文件是文件类型,mode=16822表示该文件是文件夹
同步版本:fs.statSync(path)
8、fs.watch(filename,[options],[listener])
观察指定路径的改变,filename可以是文件或者目录
//listener是一个监听器,回调函数,有2个参数:事件event和被监听文件的名称filename
9、fs.mkdir(path,[mode],callback) //mode模式,是只读还是读写模式
创建文件夹
同步版本:fs.mkdirSync(path,[mode])
10、fs.readdir(path,callback)
读取文件夹
同步版本:fs.readdirSync(path)
回调函数包括2个参数,err错误信息和当前文件夹下面所有的文件和文件夹信息fileList
11、fs.rmdir(path,callback)
删除文件夹
同步版本:fs.rmdirSync(path)
七、使用node进行web开发
1、用户上网流程
用户输入https://www.baidu.com/
通过浏览器发送https请求(类似于打电话拨号),请求baidu.com,这个域名可以转换为ip地址
通过ip定位,到网络中指定的一台机器上,然后该机器会接收到该用户发送过来的请求,然后对该请求进行处理,返回对应的内容
简言之:
用户通过浏览器发送一个http请求到指定的服务器
服务器接收到该请求,对该请求进行分析和处理
服务器处理完成之后,返回对应的数据到用户机器
浏览器接受到服务器返回的数据,并根据接收到的数据进行分析和处理
web开发:就是两台机器之间的数据交互,客户端与服务端的交互
由客户端发送一个http请求到指定的服务端 ——> 服务端接收并处理请求 ——> 返回数据到客户端,类比迅雷下载
http协议:
要进行web开发,首先就必须处理关于服务端接收请求的这一过程,所以要搭建服务器,该服务器可以接收来自任何客户端的链接和请求,然后进行对应处理
2、http模块
let http = require('http');
使用该模块可以进行服务器的搭建
server.listen(); //如果不传参数,默认系统会自动分配端口号,但是不建议,要主动设置端口号及主机名
res.writeHead( 200,'',{ //200,默认返回ok
content-type : 'text/html;charset=utf-8' //会将返回信息当成html输出到页面,html标签起作用
content-type : 'text/plain' //会将返回信息当成文本文件输出到页面,html标签不起作用
} )
/* * 搭建一个http的服务器,用于处理用户发送的http请求 * 需要使用node提供一个模块 http * */ //加载一个http模块 let http = require('http'); //通过http模块下的createServer创建并返回一个web服务器对象 let server = http.createServer(); server.on('error',(err)=>{ console.log(err) }) server.on('listening',()=>{ console.log('linstening...') }) server.on('request',(req,res)=>{ //req是客户端发送的数据,res是服务端返回的数据 console.log('有客户端请求了') //console.log(req); //req里面有请求头、域名后面附带的路径信息/a/index.html、method方式 //console.log(res); //res里面包括response正文信息(即网页上显示的内容)以及正文之外的一些信息,比如返回头信息(网页上不可见) res.writeHead('200','',{ 'content-type':'text/html;charset=utf-8' }) // res.write('<h2>hello</h2>'); // res.end(); //可以合并为一步 res.end('<h2>hello</h2>'); }) server.listen(8080,'localhost');
3、url模块
let url = require('url');
url.parse(); //专门用于解析url路径,返回json格式数据
4、使用querystring模块方法对get和post提交的数据进行处理
let qs = require('querystring');
get方式发送数据
qs.parse('foo=bar&abc=xyz&abc=123'); //{foo: 'bar',abc: ['xyz', '123']}
post方式发送数据
let http = require('http'); let url = require('url'); let fs = require('fs'); let qs = require('querystring'); let server = http.createServer(); let filename = __dirname + '/html/'; server.on('error',(err)=>{ console.log(err) }) server.on('listening',()=>{ console.log('listening') }) server.on('request',(req,res)=>{ var urlStr = url.parse( req.url ); //返回一个对象,里面的pathname属性和req.url一样 switch (urlStr.pathname) { case '/': getData(filename+'index.html',req,res); break; case '/user': getData(filename+'user.html',req,res); break; case '/login': getData(filename+'login.html',req,res); break; case '/login/check': /*console.log(req.method); //get console.log(urlStr.query); //username=xiaoxiao&password=1 console.log(qs.parse(urlStr.query)); //[Object: null prototype] { username: 'xiaoxiao', password: '1' }*/ if(req.method.toUpperCase() === 'POST'){ let str = ''; req.on('data',(chunk)=>{ str += chunk; }) req.on('end',()=>{ console.log(str); //username=13795232495&password=111 console.log(qs.parse(str)); //[Object: null prototype] { username: '13795232495', password: '111' } }) } break; default: break; } }) function getData(filename,req,res) { fs.readFile(filename,(err,data)=>{ //console.log(data.toString()); //输出页面内的全部标签内容 if(err){ res.writeHead(404,'',{ 'content-type':'text/html;charset=utf8' }) res.end('<h2>404</h2>') }else{ res.writeHead(200,'',{ 'content-type':'text/html;charset=utf8' }) res.end(data) } }) } server.listen(8082,'localhost');
/* * 搭建一个http的服务器,用于处理用户发送的http请求 * 需要使用node提供一个模块 http * */ //加载一个http模块 let http = require('http'); let url = require('url'); //通过http模块下的createServer创建并返回一个web服务器对象 let server = http.createServer(); server.on('error',(err)=>{ console.log(err) }) server.on('listening',()=>{ console.log('linstening...') }) server.on('request',(req,res)=>{ //req是客户端发送的数据,res是服务端返回的数据 console.log('有客户端请求了') console.log(req.url); //req里面有请求头、域名后面附带的路径信息/a/index.html、method方式 //console.log(res); //res里面包括response正文信息(即网页上显示的内容)以及正文之外的一些信息,比如返回头信息(网页上不可见) switch (req.url) { case '/': res.writeHead(200,'',{ 'content-type':'text/html;charset=utf-8' }) res.end('<h2>这是首页</h2>'); break; case '/user': res.writeHead(200,'',{ 'content-type':'text/html;charset=utf-8' }) res.end('<h2>这是用户页</h2>'); break; default: res.writeHead(404,'',{ 'content-type':'text/html;charset=utf-8' }) res.end('<h2>404</h2>'); break; } // res.write('<h2>hello</h2>'); // res.end(); //可以合并为一步 //res.end('<h2>hello</h2>') }) server.listen(8080,'localhost');
【注意】:
1、所谓异步,就是执行成功了之后会执行一个回调函数,下面的代码会继续执行,即使报错了也不妨碍下面代码的执行;同步,就是成功了就继续执行下面的代码,报错了就卡在这儿了,下面的代码也就执行不了了。
2、所谓的参数filename,包括文件的名称和路径(如果有路径的话),比如在task文件夹下创建index.html
那么filename='task/index.html'
要包括文件的名称,不能仅仅是一个空路径,'task/'
以上是“nodejs有什么作用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。