文章目录
- 前言
- Node.js对比JS
- 网址
- 特点
- 运行方式
- 一.Node.js概述
- 1.全局对象
- (1) global
- (2) console 对象
- (3)process 对象
- (4)Buffer 对象
- 二.模块
- 1.模块分类
- 2.包和npm
- (1) 切换命令行的路径
- (2)下载
- 3.查询字符串(querystring)
- 4.URL模块
- 5.定时器模块(timer)
- (1)一次性定时器
- (2)周期性定时器
- (3)立即执行定时器
- 6.文件系统模块( fs )
- (1)创建目录
- (2)移除目录
- (3)查看文件的状态
- (4)读取文件目录
- (5)写入文件
- (6)追加写入
- (7)读取文件
- (8)删除文件
- (9)检测文件是否存在
- (10)拷贝文件
- (11)文件流和事件
- 7.同步和异步
- (1).同步:在执行的过程中按照顺序执行,会阻止后续代码的执行,如果获取结果通过返回值
- (2).异步:在执行的过程中如果有异步操作,会在一个独立的线程执行,不会阻止主程序中后续代码的执行;通过回调函数获取结果
- 8.http协议
- (1)通用的头信息
- (2)响应的头信息(Response)
- (3)请求的头信息(Request)
- (4)请求主体
- 9.http模块
- 三.express 框架
- (1) 创建WEB服务器
- (2) 路由
- 四.路由器
- 路由器
- web服务器
- 五.中间件
- (1)应用级中间件
- (2)路由级中间件
- (3)内置中间件
- (4)第三方中间件
- 六.mysql 模块
- (1)创建普通连接
- (2)创建连接池
- (3)执行SQL命令
- (4)SQL命令中的占位符
前言
Node.js是基于谷歌的V8引擎,是一种运行在服务器端的JS解释器,可以实现所有后端语言的功能,例如java,php等能做的Node.js也可以。
www.nodejs.org 官网
www.nodejs.cn 中文镜像
对比JS和Node.js
JS运行在客户端浏览器,存在多款浏览器有兼容性问题;Node.js运行在
服务器端,只能谷歌V8引擎一种解释器,不存在兼容性问题;
两者都有ES(内置)对象,自定义对象;不同的宿主对象。
JS用于开发浏览器端交互效果,Node.js用于服务器的操作,例如数据库访问,网络操作等…
Node.js适合做IO操作为主应用,不适合做CPU密集型的应用。
特点
Node.js属于单线程运行逻辑,默认只使用其中一个CPU内核
支持数万个并发连接,适合开发大规模的WEB应用
运行方式
脚本模式
node 拖拽文件 回车
交互模式
node 回车 进入交互模式
两次ctrl+c 退出交互模式
在说Node.js之前,咱们先来了解一下Node.js的基本操作
Node.js对比JS
JS运行在客户端路蓝旗,存在多款浏览器,有兼容性问题;Node.js运行在服务器端,只有一种解释器,没有兼容性问题。
两者有共同的内置对象、自定义对象;以及各自宿主对象。
JS用于开发浏览器端的交互效果;Nodejs用于服务器端的开发,例如数据库访问、WEB服务器的创建…
网址
官网:www.nodejs.rog
中文翻译:www.nodejs.cn
node -v
查看版本号
特点
Node.js属于单线程运行逻辑,默认只使用其中一个CPU内核
支持数万个并发连接,适合开发大规模的WEB应用
运行方式
脚本模式
node 拖拽文件
回车
交互模式
node 回车 进入交互模式
两次ctrl+c
退出交互模式
一.Node.js概述
1.全局对象
(1) global
用于查看一个变量和函数是否为全局变量或者全局函数
global.变量 global.函数名称()
在node.js脚本文件中不是在全局作用域下,里边的变量和函数都是局部的,可以有效防止全局污染。
在JS脚本文件中是在全局作用域下,全局对象叫 window
,里边的变量和函数都是全局的,会存在全局污染。
例:编写脚本文件03_global.js,声明变量,创建函数;查看里边的变量和函数是否为全局的。
var a=1;
function func(){
return 3;
}
//nodejs下脚本文件不是全局作用域
//a和func都是局部的,不能使用global访问
console.log( global.func() ); //运行结果:不是全局的
(2) console 对象
console.log( ) 打印日志
console.info() 打印消息
console.warn() 打印警告
console.error( 打印错误
console.time( 开始计时
console.timeEnd() 结束计时
(3)process 对象
进程:计算机上每一个软件启动后都是有一个进程。
process.arch 查看当前CPU的架构
process.platform 查看当前的操作系统
process.version 查看当前node.js的版本号
process.pid 查看当前进程的编号
process.kill(进程编号) 结束制定编号的进程
(4)Buffer 对象
Buffer:缓冲区、缓冲器,内存中存储数据的区域,常用于存储网络传输的资源。
let buf=Buffer.alloc(5,'abcde'); //创建buffer空间并存储数据,每个英文字符占1个字节,汉字占3个字节
buf.toString()//将buffer转为字符串
String(buf)//将buffer转为字符串
二.模块
Node.js下,每个模块是一个功能体。
分为自定义模块
、核心模块
、第三方模块
每一个文件就是一个模块
module:当前模块的对象
require:是一个函数,用于导入另一个模块
module.exports:导出的对象,默认是一个空对象,如果要导出内容,需要放入到该对象。
__dirname:directory 当前模块的绝对路径
__filename:当前模块的绝对路径+模块名称
1.模块分类
以路经开头 | 不以路径开头 | |
---|---|---|
文件模块 | require(’./circle.js’) 常用于引入自定义以内 | require(‘querystring’) 用于引用官方提供的核心模块 |
目录模块 | require(’./02_dong’) 首先会到目录下寻找package.json文件中main对应的文件; 如果没有会自动赵找index.js | equire(‘ran’) 首先会到当前目录下的node_modules目录中寻找ran目录; 如果找不到会一直往上一级的node_modules中寻找ran目录;常用于第三方模块** |
json文件:属于一种数据文件,通常放数组和对象,对象的属性名必须用双引号,字符串必须用双引号。
2.包和npm
包:package,就是目录模块,也是第三方模块的叫法
npm:用于管理包的工具,包含有下载安装、升级、卸载、上传…
npm会在node.js安装时附带安装
npm -v
查看npm版本号
(1) 切换命令行的路径
① cd 粘贴路径 回车
如果涉及到盘符的变化,需要添加 盘符名称:
回车
② 在指定的目录下的空白区域按住shift鼠标右击选择’在此处打开 powershell窗口’
(2)下载
网址:www.npmjs.com
npm installl 包名称
回车
将包自动放到node_modules目录中,这个 目录不存在自动创建。,可能会下载一些其他依赖的包。同时还会产生一个package-lock.json的文件,用于记录包的版本号。
3.查询字符串(querystring)
查询字符串:浏览器向web服务器发送请求,传递数据的一种方式,位于URL中问号后的部分。
keyword=123&enc=utf-8
查询字符串模块用于操作查询字符串的工具模块。
parse()
将查询字符串解析为对象
例:获取以下查询字符串中商品的名称和价格:pname=apple&price=5199
const querystring=require('querystring');
var str='pname=apple&price=5199';
let obj=querystring.parse(str);
console.log(obj.pname);
console.log(obj.price);
4.URL模块
URL:统一资源定位,网络上的任何资源都有对应的URL
http:// www.codeboy.com: 9999/ prodects.html? kw=dell
协议 域名/IP地址 端口 文件在服务器上的路径 查询字符串
URL模块用于操作 URL
parse()
将一个URL解析为对象,可以得到URL中的各个部分。
5.定时器模块(timer)
(1)一次性定时器
//开启
let timer=setTimeout(回调函数,间隔时间);
//当间隔时间到了,会调用一次回调函数,单位是毫秒
//清除
clearTimeout(timer);
(2)周期性定时器
//开启
let timer=setInterval(回调函数,间隔时间);
//每个一段时间,调用一次糊掉函数
//清除
clearInterval(timer);
例:两秒打印一次,打印3次后,清除定时器
let i=0;
let timer=setInterval(()=>{
console.log('boom');
i++;
if(i===3){
clearInterval(timer);
}
},2000);
(3)立即执行定时器
//第一种
//开启
let timer=setImmediate(回调函数);
//清除
clearImmediate(timer)
//第二种
process.nextTick(回调函数)
6.文件系统模块( fs )
文件包括文件形式和目录形式
(1)创建目录
fs.mkdirSync(目录的路径)
(2)移除目录
fs.rmdirSync(目录的路径)
(3)查看文件的状态
statSync(文件的路径)/stat(文件的路径,回调函数)
回调函数:异步操作通过回调函数获取结果
err:可能产生的错误
s:具体的文件状态
s.isFile() 是否为文件
s.isDirectory 是否为目录
(4)读取文件目录
readdir(文件路径,回调函数)
获取的结果为数组形式
//异步
fs.readdir('../day02',(err,arr)=>{
if(err) throw err;
//读取的目录文件
console.log(arr);
});
console.log('运行结束');
readdirSync(文件路径)
获取的结果为数组形式
let s=fs.readdirSync('../day02');
console.log(s);
console.log('运行结束');
(5)写入文件
wirteFileSync(文件的路径,写入的数据)
wirteFile(文件的路径,写入的数据,回调函数)
fs.writeFile('./1.txt','range',(err)=>{
if(err) throw err;
console.log('写入成功');
})
如果文件不存在,则会创建文件后写入文件
如果文件已经存在,则会原来基础上覆盖写入
(6)追加写入
appendFileSync(文件的路径,写入的数据)
/ appendFile(文件的路径,写入的数据,回调函数)
如果文件不存在,则会创建文件然后写入数据
如果文件已经存在,则会在文件的末尾追加写入数据
例:使用异步的方法往文件3.txt中追加写入数据 Hello你好
fs.appendFile('./3.txt','Hello你好',(err)=>{
if(err) throw err;
})
(7)读取文件
readFileSync(文件的路径)
/ readFile(文件的路径,回调函数)
读取的结果为buffer数据
//异步,读取stu.txt
fs.readFile('./stu.txt',(err,data)=>{
if(err) throw err;
console.log( String(data) );
});
//同步,读取3.txt
let s=fs.readFileSync('./3.txt');
console.log( String(s) );
(8)删除文件
unlinkSync(文件的路径)
/ unlink(文件的路径,回调函数)
例:使用异步方法删除1.txt
fs.unlink('./1.txt',(err)=>{
if(err) throw err;
})
(9)检测文件是否存在
existsSync(文件的路径)
true —> 存在 false—> 不存在
注:只能用同步 不能用异步
例:如果文件2.txt存在,则同步删除该文件;如果目录mydir2不存在,则同步创建该目录
if( fs.existsSync('./2.txt') ){
fs.unlinkSync('./2.txt');
}
if(!fs.existsSync('./mydir2')){
fs.mkdirSync('./mydir2')
}
(10)拷贝文件
copeFileSync(源文件,目标文件)
/ copeFile(源文件,目标文件,回调函数)
例:拷贝文件3.txt到mydir下
fs.copyFile('./3.txt','./mydir/3.txt',(err)=>{
if(err) throw err;
console.log('拷贝成功');
})
例:同步拷贝stu.txt到mydir下
let s=fs.copyFileSync('./stu.txt','./mydir2/stu.txt');
console.log('拷贝成功');
(11)文件流和事件
createRreadStream(文件的路径)
创建可读取的流对象
createWriteStream(文件的路径)
创建可写入的流对象
事件格式
on('事件名称',回调函数)
事件名称是固定用法,一旦触发事件自动执行回调函数
PS:pipe( )
管道,可以将读取的流添加到写入流
7.同步和异步
(1).同步:在执行的过程中按照顺序执行,会阻止后续代码的执行,如果获取结果通过返回值
//同步:从上往下执行
let s=fs.statSync('../day02');
console.log(s);
//查看是否为文件
console.log(s.isFile());
//查看是否为目录
console.log(s.isDirectory());
同步打印的返回值会根据上述代码的书写顺序一致
(2).异步:在执行的过程中如果有异步操作,会在一个独立的线程执行,不会阻止主程序中后续代码的执行;通过回调函数获取结果
let s=fs.stat('./01_homework.js',(err,s)=>{
//err,可能产生的错误
if(err){
throw err;
}
//s获取的文件的状态
console.log(s);
});
console.log('运行结束');
异步打印的返回值顺序会根据代码里各自逻辑的执行速度而定,哪个先执行完哪个先打印
下图是本次异步打印的结果,最下面的外层打印比上面的函数先执行完,所以外层先打印结果
8.http协议
浏览器和web服务器之间的通信协议
(1)通用的头信息
Request URL:请求的URL,像服务器端请求的内容
Request Method:请求的方法,get
/ post
Status Code:响应的状态码
1xx 系列:正在响应,还没有结束
2xx 系列:成功的响应
3xx 系列:响应的重定向,跳转到另一个URL
4xx 系列:客户端请求错误
5xx 系列:服务器端错误
(2)响应的头信息(Response)
Content-Type:相应的内容类型,html文件对应 text/html
Content-Length: 响应的文件长度,单位是字节
Location:要跳转的URL,需要结合着状态码3**使用
(3)请求的头信息(Request)
浏览器发出的叫做请求
(4)请求主体
传递的数据,例如注册、登陆传递数据
可有可无,没有传递数据,这项不显示。
9.http模块
可以创建web服务器,接收浏览器的请求并作出相应
const app=http.createServer(); //创建web服务器
app.listen(8080); //设置端口,用于访问web服务器
//添加事件,通过事件来接收请求并做出响应
app.on('request',(req,res)=>{
//req //请求的对象
//req.url //获取请求的url,对应端口号后的部分
//req.method //获取请求的方法
//res //响应的对象
res.write() //设置响应的内容
res.writeHead() //设置响应的状态码和头信息,第二个参数头信息可以为空
res.end() //结束并发送响应
})
三.express 框架
一整套的解决方案,把用得到的功能都做到了并简化。express
基于Node.js
平台,快速、开放、极简的WEB开发框架
网址:www.expressjs.com.cn
下载:npm install express
(1) 创建WEB服务器
//引入第三方模块
const express=require('express');
//创建web服务器
const app=express();
//设置端口
app.listen(8080);
(2) 路由
浏览器向web服务器发送请求,web服务器端根据请求的方法和请求的URL做出响应,用来处理特定的请求。
路由的组成:请求的方法
、请求的URL
、回调函数(用来响应)
响应对象:
send()
设置响应的内容并发送
redirect()
设置响应的重定向,跳转到另一个URL
sendFile()
设置响应的文件,需要绝对路径 __dirname
例:根据表单提交的请求来创建对应的路由(post/mylogin),响应’登陆成功’
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>用户登陆</h2>
<!-- form 用于表单提交,相当于向服务器发送请求
method 设置请求的方法
action 设置请求的URL
name 保存输入的值
-->
<form method="POST" action="/mylogin">
用户:<input type="text" name="uname"><br>
密码:<input type="text" name="upwd"><br>
<input type="submit" >
</form>
</body>
</html>
Node.js代码:
app.post('/mylogin',(req,res)=>{
//获取post请求的方法
//以流的方式传递,通过添加事件获取
//一旦数据流入,自动触发事件,通过回调函数获取数据
req.on('data',(chunk)=>{
console.log(chunk);//Buffer格式
let str=String(chunk);
console.log(str);
//查询字符串,解析为对象
let obj=querystring.parse(str);
console.log(obj);
})
res.send('登陆成功');
});
传递方式 | 类型 | 在路由中获取 |
---|---|---|
post传递 | 不可见 | req.on(‘data’,(chunk)=>{ chunk 就是获取的数据,格式为buffer,需要转字符串, 转字符串后为查询字符串,需要解析为对象 }) |
查询字符串传递 | 在URL中可见 kw=dell&price=4000 | req.query 格式为对象 |
路由传参 | 在URL中可见 /package/mysql | 需要在路由的URL中指定形参 app.get(’/package/:pname’,(req,res)=>{ req.params //获取路由传参的数据,格式为对象 }) |
对比post和get的区别
post传递的数据不可见,get可见
post可以传递大文件,get方式只能通过url中传递字符串,长度不超过4k
post传递的速度相对get慢
通常登陆、注册使用post请求,搜索使用get请求
四.路由器
用来管理路由,将同一个模块下的路由归纳到一起;可以有效的进行分工协作,还可以防止URL冲突。
路由器
const express=require('express');
//创建路由器对象
const r=express.Router();
//往路由器下添加路由
r.get('/list',(req,res)=>{
res.send('这是用户列表');
});
//导出路由器对象
module.exports=r;
web服务器
//引入自定义的模块user.js
const userRouter=require('./user.js');
//挂载并添加前缀
app.use('/user',userRouter);
五.中间件
用于拦截对路由的请求,最终是为路由服务的。
中间件分为应用级中间件、路由级中间件、内置中间件、第三方中间件、错误处理中间件
(1)应用级中间件
也称为自定义中间件,是一个中间件的函数,一旦拦截就会调用
app.use(要拦截的URL,回调函数)
在回调函数中有三个参数 req、res、next
next
表示往后执行,可能是下一个中间件或者路由
例:创建web服务器,添加用户数据列表的路由(get /list),响应’这是所有用户的数据’,添加中间件,拦截对URL为 /list的请求,验证用户是否为管理员,如果不是管理员root,则响应’请提供管理员账户’
// 引入第三方express模块
const express=require('express');
// 创建web服务器
const app=express();
// 设置端口
app.listen(8080);
//添加中间件,拦截对URL为 /list的请求
//一旦拦截调用回调函数
//中间件回调函数也有请求对象和响应对象
app.use('/list',(req,res,next)=>{
//获取查询字符串传递的数据
console.log(req.query);
//验证用户是否为管理员
//如果不是管理员root,则响应'请提供管理员账户'
if(req.query.uname!=='root'){
res.send('请提供管理员账户');
}else{
//往后继续执行,可能是中间件或者是路由
next();
}
});
app.get('/list',(req,res)=>{
res.send('这是所有用户的数据');
});
(2)路由级中间件
路由器的使用
app.use( URL,引入的路由器);
(3)内置中间件
托管静态资源( html,css , js , img )
浏览器端向服务器端请求静态资源文件,不需要添加路由去寻找斌响应文件,而是将静态资源文件托管到指定的目录下,让浏览器自动去找。
app.use( express.static('目录的路径') )
例:创建web服务器,添加静态资源到public目录下,目录中添加登陆的网页login.html,点击提交向服务器发送请求( post /mylogin),创建对应的路由,获取用户和密码,并响应’登陆成功’
const express=require('express');
const querystring=require('querystring');
// 创建web服务器
const app=express();
// 设置端口
app.listen(8080);
// 添加静态资源到public目录下
app.use(express.static('./public'));
app.post('/mylogin',(req,res)=>{
req.on('data',(chunk)=>{
let obj=querystring.parse(String(chunk));
console.log(obj);
res.send('登录成功');
});
});
<h2>用户登录</h2>
<form method="POST" action="/mylogin">
用户<input type="text" name="uname"><br>
密码<input type="password" name="upwd"><br>
<input type="submit">
</form>
(4)第三方中间件
属于是第三方的模块
以body-parse
为例
下载安装:npm install body-parse
通常会伴随express
下载安装
//1.引入body-parser模块
const bodyParser=require('body-parser');
//2.使用body-parser中间件将post请求的数据解析为对象
app.use( bodyParser.urlencoded({
extended:false //是否使用扩展的qs,true表示使用 false会使用querystring
}) );
//3.在路由中获取数据,格式为对象
req.body
六.mysql 模块
之所以把mysql模块单独拿出来说,是因为mysql模块是常用而且必会的
Nodejs 下用于操作mysql
数据库的模块
下载安装:npm install mysql
完整的连接
mysql.exe -h127.0.0.1 -P3306 -uroot -p
(1)创建普通连接
mysql.createConnection( )
(2)创建连接池
mysql.createPool( )
(3)执行SQL命令
query(SQL命令,回调函数)
通过回调函数获取结果
例:查询出emp数据表里编号为5的所有数据
pool.query('select * from emp where eid=5',(err,result)=>{
if(err) throw err;
console.log(result);
});
(4)SQL命令中的占位符
防止SQL注入,将用户提供的值进行过滤,过滤后再替换占位符
pool.query( 'select * from emp where eid=?',['5 or 3=3'],(err,result)=>{
if(err) throw err;
console.log(result);
} )