1.Node.js概述
基于谷歌的V8引擎,运行在服务器端的JS解释器。
官网:www.nodejs.org
中文镜像:www.nodejs.cn
(1)对比JS和Node.js
JS运行在客户端浏览器,存在多款浏览器,有代码兼容性问题;Node.js运行在服务器端,只有V8引擎一种环境,不存在兼容性问题。
两者都有的自定义对象和内置对象,不同的宿主对象
两者的作用不同,JS用于开发浏览器端交互效果,Node.js用于服务器端的开发,例如数据库的访问、其它服务器的访问...
(2)运行Node.js
脚本模式
node 拖拽文件 回车
交互模式
node 回车 进入交互模式
ctrl+d / 连续两次ctrl+c 退出交互模式
(3)应用场景
属于单线程运行逻辑,适合做基于社交网络的大规模WEB应用,在线人数比较多;不适合做CPU密集型应用...
2.全局对象
(1)global
检测一个变量或者函数是否为全局的,如果能够通过global来访问说明是全局的
练习:编写脚本文件03_global.js,在文件中声明变量a,创建函数fn;通过global查看是否为全局。
var a=1;
function fn(){
return 2;
}
console.log(global.a);
console.log(global.fn());
//console.log( global.a );//a不是全局的
//console.log( global.fn() );//fn不是全局的
在JS下的global叫window
练习:编写文件04_window.js和04.html,把js文件嵌入到html中,在js文件中声明变量和创建函数,使用window访问,查看是否为全局变量和全局函数
var a=1;
function fn(){
return 2;
}
console.log( window.a );
console.log( window.fn() );
在Node.js下,每个文件是在一个模块作用域下,里边的变量和函数都是局部的,不存在全局污染。
在JS下,每个文件都是在全局作用域,里边的变量和函数都是全局的,存在全局污染。
(2)console对象
log() 打印日志
info() 打印消息
warn() 打印警告
error() 打印错误
time() 开始计时
timeEnd() 结束计时
说明:time和timeEnd中的参数要保持一致。
练习:分别统计for、while、do-while循环100000次的耗时
//开始计时
console.time('ran');
for(var i=1;i<=100000;i++){
}
//结束计时
console.timeEnd('ran');
console.time('while');
var j=1;
while(j<=100000){
j++
}
console.timeEnd('while');
console.time('dowhile');
var k=1;
do{
k++;
}while(k<=100000);
console.timeEnd('dowhile');
(3)process对象
进程
process.arch 查看当前CPU的架构
process.platform 查看当前的操作系统
process.version 查看当前Node.js的版本号
process.pid 查看当前Node.js进程的编号
process.kill(进程编号) 结束指定编号的进程
(4)Buffer对象——缓冲器、缓冲区
Buffer数据:存储在缓冲区中的数据,通常用于存储网络传输时的资源
var buf=Buffer.alloc(5, 'abcde')// 创建buffer,并存储字符
buf.toString() / String(buf) //将buffer数据转为字符串
3.模块
模块是一个独立功能体,每个文件就是一个模块
分为自定义模块、核心模块、第三方模块
require() 引入其它的模块,得到该模块导出的对象
module.exports 导出的对象,默认是一个空对象,如果要导出哪些内容,只需要放入到这个空对象即可。
1.模块内的关键字
require: 是一个函数,用于引入其它的模块
module.exports: 是一个对象,代表当前模块导出的对象
__dirname: 是一个变量,代表当前模块的绝对路径
__filename: 是一个变量,代表当前模块的绝对路径+模块名称
2.模块的分类
练习:在03_1.js模块中,引入同一级目录下的目录模块03_2,包含文件index.js,导出一个函数,计算任意两个数字的和;最后在03_1.js中调用该函数
练习:在04目录下,创建文件04_1.js,引入同一级目录下目录模块ran,包含文件index.js,打印‘找到了哥’;
3.包和npm
包(package):是第三方的模块,属于目录模块
npm:用来管理包的工具,在Node.js安装的时候附带安装,例如上传、下载、升级、卸载...
npm -v 查看npm版本号
网址:www.npmjs.com
(1)切换命令行的路径
方法1:
cd 路径 回车
盘符名称: 如果涉及到盘符的切换,需要添加这步
方法2:
在要进入的目录的空白区域,按住shift键,单击鼠标右键 -> 在此处打开powershell窗口
(2)使用npm
npm init -y 生成一个package.json文件,称作项目说明文件,可以记录下来安装的包
npm install 包的名称 下载安装指定的包,同时会下载其它依赖的包,将这些包放入到node_modules目录中;会生成一个package-lock.json,用于记录当前所有安装的包的版本号。
npm install 下载package.json和package-lock.json中记录的包
npm run 快捷名称 会到package.json中scripts下找对应的快捷名称然后运行
npm config get registry 查看下载包的服务器地址
npm config set registry https://registry.npm.taobao.org/ 更改下载包的服务器地址为淘宝镜像(国内)
(3)npx
在npm5.2后附带安装的一个工具
npx -v 查看npx的版本号,通常和npm的版本相同
npx -p node@版本号 node 文件名称 先去下载指定版本的Node.js,然后再使用这个版本的Node.js去运行文件;当运行完以后再把下载的Node.js删除
可以在不改变当前Node.js版本的情况下,使用其它Node.js版本。
4.查询字符串模块(querystring)
查询字符串:浏览器向服务器发请求传递数据的一种方式,位于浏览器的地址栏
https://search.jd.com/Search?keyword=手机&enc=utf-8
查询字符串模块用于操作查询字符串的工具模块
parse() 将查询字符串解析为对象,可以获取传递的数据。
练习:获取以下查询字符串中传递的数据,
lid=22&count=1
最终打印成以下形式
商品的编号:xx
购买的数量:x
5.URL模块
URL:统一资源定位,互联网上的任何资源(html,css,js...数据)都有对应的URL来访问。
http://www.codeboy.com:9999/product_details.html?lid=17#product_introduction
协议 域名/IP地址 端口 文件在服务器的路径 查询字符串 锚点(当前页面跳转)
URL模块用来操作URL的工具模块
parse() 将URL解析为对象,可以获取其中各个部分
练习:从以下URL中获取查询字符串传递的数据
https://www.tmooc.cn:443/web/course.html?cid=2012&cname=nodejs#qs
最后打印出
班级名称:2012
课程名称:nodejs
6.定时器模块(timer)
属于全局的,不需要引入模块,提供一组定时器函数
(1)一次性定时器
开启
var timer=setTimeout(回调函数, 间隔时间);
当间隔时间到了,会调用一次回调函数
清除
clearTimeout(timer)
(2)周期性定时器
开启
var timer=setInterval(回调函数, 间隔时间)
每隔一段时间,会调用一次回调函数
清除
clearInterval(timer);
(3)立即执行定时器
开启
var timer=setImmediate(回调函数);
清除
clearImmediate(timer);
process.nextTick(回调函数)
将回调函数放入到事件队列,当主程序执行完以后再执行事件队列中的回调函数。
练习
开启周期性定时器,打印3次 hello 后,结束定时器。
var count=0;
var timer=setInterval(()=>{
console.log(1);
count++;
//判断是否为3次
if(count===3){
clearInterval(timer);
}
},2000);
7.同步和异步
同步:在主程序中执行,会阻止后续代码的执行,通过返回值来获取结果
异步:在一个独立的线程执行,不会阻止主程序中后续代码的执行,通过回调函数来获取结果
8.fs模块
文件系统模块:用于操作服务器端的文件
文件分为两种形式:文件形式和目录形式
(1)查看文件的状态
fs.statSync(文件的路径)/fs.stat(文件的路径, 回调函数)
回调函数:用于获取异步操作的结果
err:可能产生的错误
s:具体获取到的结果
isDirectory() 是否为目录
isFile() 是否为文件
(2)创建目录
fs.mkdirSync(目录的路径)/fs.mkdir(目录的路径, 回调函数)
(3)移除目录
fs.rmdirSync(目录的路径)/fs.rmdir(目录的路径, 回调函数)
练习:分别使用同步和异步移除mydir和mydir2
不允许移除有文件的目录,只能移除空的目录
(4)读取目录
fs.readdirSync(目录的了路径)/fs.readdir(目录的路径, 回调函数)
读取的结果是数组的格式
(5)覆盖写入文件
fs.writeFileSync(文件的路径, 写入的数据)/fs.writeFile(文件的路径, 写入的数据, 回调函数)
如果文件不存在,会先创建文件然后写入数据
如果文件已经存在,会清空原来的内容然后写入数据
(6)追加写入文件
fs.appendFileSync(文件的路径, 写入的数据)/fs.appendFile(文件的路径, 写入的数据, 回调函数)
如果文件不存在,会先创建文件然后写入数据
如果文件已经存在,会在文件的末尾追加写入数据
练习:使用同步方法往2.txt追加写入数据 ‘你好’,运行多次
(7)读取文件中的数据
readFileSync(文件的路径) / readFile(文件的路径, 回调函数)
读取到的数据格式为buffer格式
(8)删除文件
unlinkSync(文件的路径) / unlink(文件的路径, 回调函数)
(9)检测文件(目录)是否存在
existsSync(文件的路径)
练习:如果文件2.txt存在则删除该文件,如果目录mydir不存在则创建该目录
(10)拷贝文件
copyFileSync(源文件的路径, 目标文件的路径)
copyFile(源文件的路径, 目标文件的路径, 回调函数)
(11)文件流
createReadStream() 创建可读取的文件流
createWriteStream() 创建可写入的文件流
pipe() 管道,可以将读取的文件流添加到写入的文件流,完成文件的拷贝
on(事件名称, 回调函数) 添加事件,事件名称是字符串格式,是固定用法;一旦触发事件,自动调用回调函数
2.http协议
浏览器和web服务器之间的通信协议
(1)通用头信息
Request URL:请求的URL,代表请求的资源
Request Method:请求的方法,对资源的操作方式
Status Code:响应的状态码
1:接收了请求还没做出响应
2:成功的响应
3:响应的重定向
4:客户端请求错误
5**:服务器端错误
(2)响应头信息 Response
Content-Type:响应的内容类型 如果是html类型对应 text/html
Location:要跳转的URL,通常结合状态码3**使用
(3)请求头信息
(4)请求主体
可有可无,包含客户端在请求过程中传递的数据
3.http模块
可以用来创建web服务器,用来给客户端提供资源
//引入http模块
const http=require('http');
//创建web服务器
const app=http.createServer();
//设置端口,用于访问web服务器
app.listen(8080);
//通过事件接收请求并作出响应
app.on('request',(req,res)=>{
req 请求的对象
req.url 获取请求的URL(资源)
req.method 获取请求的方法
res 响应的对象
res.write() 设置响应到浏览器的内容
res.writeHead() 设置响应的状态码和头信息
res.end() 结束并发送响应
});
练习:创建web服务器,设置端口,根据请求的URL(资源)做出响应
/index这是首页
/study 跳转到 http://www.tmooc.cn
/list 响应文件 list.html,(先读取文件的数据,然后把数据作为响应的内容)
其它 404 not found
const http=require('http');
const fs=require('fs');
//创建web服务器
const app=http.createServer();
//设置端口
app.listen(8080);
//添加事件,接受请求并做出响应
app.on('request',(req,res)=>{
//根据请求的URL来做出响应
//req.url 请求的服务器端的资源 /xxx
if(req.url==='/index'){
res.writeHead(200,{
//设置显示的内容类型和编码
'Content-Type':'text/html;charset=utf-8'
});
res.write('这是首页
');
//res.end();
}else if(req.url==='/study'){
res.writeHead(302,{
Location:'http://www.tmooc.cn/'
});
//res.end();
}else if(req.url==='/list'){
//读取list.html文件中的内容
//格式为buffer
var data=fs.readFileSync('./list.html');
//把读取到的内容,设置为响应到浏览器的内容
//buffer数据隐式转换为了字符串
res.write(data);
}else{
res.writeHead(404);
res.write('not found');
}
//无论响应什么内容,最终都要结束并发送
res.end();
});