(1)对比JS
(2)网址
www.nodejs.org
官网
www.nodejs.cn
中文镜像
(3)使用Node.js
脚本模式
node 拖拽脚本文件 回车
交互模式
node 回车 进入交互模式
两次ctrl+c 或者 ctrl+d
(4)特点
var a = 1;
function fn(){
return 2;
}
//报错,都不是全局下的
//console.log( global.a );
//console.log( global.fn() );
以下是运行在html中, 打开页面, F12 选择(console) 控制台 查看结果
var a = 1;
function fn(){
return 2;
}
console.log( window.a );
console.log( window.fn() );
console.log(1) //日志
console.info(2) //消息
console.warn(3) //警告
console.error(4) //错误
console.time() 开始计时
console.timeEnd() 结束计时
开始计时和结束计时的参数要保持一致
//注意:要在html中运行查看
console.log(1); //日志
console.info(2);//消息
console.warn(3);//警告
console.error(4);//错误
进程:计算机让的软件运行都是代表相应的进程
process.arch
查看当前CPU架构
process.platform
查看当前的操作系统
process.version
查看当前Node.js版本
process.pid
查看当前Node.js进程编号
process.kill()
结束指定编号的进程
缓冲器:在内存临时存储数据的区域,常用于保存网络传输时的资源
let buf = Buffer.alloc(5,'abcde');
//创建Buffer,大小为5个字节(汉字占3个字节)
buf.toString()
//将Buffer数据转为字符串
//创建Buffer
//一个汉字占3个字节
let buf = Buffer.alloc(9,'abc涛桑');
console.log(buf);
//将buffer转为字符串
console.log( buf.toString() );
开启
var timer = setTimeout( 回调函数, 间隔时间 )
当间隔时间到了,调用一次回调函数
---------------------------------------------
清除
clearTimeout(timer)
//一次性定时器
//开启: 3秒钟后打印一次boom
var timer = setTimeout(function(){
console.log('boom');
},3000);
//---------------------------------------------
//立即清除
//clearTimeout(timer);
//console.log(1);
例如: 轮播图就是一个定时器,每隔几秒钟切换一次,进入死循环
开启
let timer = setInterval(回调函数,间隔时间)
每隔一段时间,调用一次回调函数
---------------------------------------------
清除
clearInterval(timer)
//开启周期性定时器
let timer = setInterval(function(){
console.log('滴滴滴');
},3000);
//3000代表3秒,表示使'滴滴滴'进入死循环,每隔3秒钟打印一次
//清除
//clearTimeout(timer)
立即执行定时器没有间隔时间 , 只有回调函数 , 如果遇到特别耗时的 , 就把他放到最后 , 不然会影响主程序的执行
开启
let timer=setImmediate(回调函数)
每隔一段时间,调用一次回调函数
---------------------------------------------
清除
clearImmediate(timer)
---------------------------------------------
开启
process.nextTick(回调函数)
//立即执行定时器
console.log(2);
setImmediate( ()=>{
console.log(1);
} );
process.nextTick( ()=>{
console.log(4);
} );
console.log(3);
//运行结果:2 3 4 1
是一个独立的功能体, 模块可以被其它的模块引入, 也可以引入其它的模块
require()
用于引入其它的模块
module.exports
是一个空对象,用于存放导出的内容
__dirname
当前模块的绝对目录
__filename
当前模块的绝对目录+模块名称
示例:创建主模块(08_tou.js)和功能模块(08_yan.js),在功能模块下导出一个变量和一个函数
在主模块下引入成功后,调用这个变量和函数
主模块文件: 08_tou.js
//引入08_yan.js模块
//引入同一级的模块写路径 ./
//上一级 ../
//上上级 ../../
//引入模块得到的是该模块导出的对象
var obj = require('./08_yan.js');
//使用另一个模块中的变量和函数
console.log(obj);
console.log(obj.mya, obj.myfn());
功能模块文件: 08_yan.js
var a = 1;
function fn(){
return 2;
}
//module.exports 就是导出对象,默认是一个空对象
//往导出对象中添加要导出的内容
module.exports = {
mya: a,
myfn: fn
}
__dirname 和 __filename
//两个局部变量,每个模块下自带的
console.log( __dirname ); //绝对目录
console.log( __filename ); //绝对目录+模块名称
方法1:
方法2:
windows+r
输入cmd
进入npm -v
查看版本号npm init -y
初始化一个package.json文件,是项目描述文件,可以记录下安装的包npm install
包的名称 下载安装包,将包放入到node_modules目录中,如果这个目录不存在会自动创建,同时会生成package-lock.json文件,记录所有包的版本号;在package.json中会记录安装的这个包的信息。npm install
自动去安装package.json和package-lock.json中记录的包npx -p node@8 node 文件路径
下载指定版本的nodejs,然后运行文件,运行完会将下载的nodejs删除parse()
将查询字符串解析为对象 *引入查询字符串模块*
const querystring = require('querystring');
console.log(querystring);
打印出的结果是一个对象, 对象里面则是模块, 导出的里面就是模块提供给我们的方法
//引入查询字符串模块
const querystring = require('querystring');
//console.log(querystring);
//查询字符串
let str = 'keyword=电脑&enc=utf-8';
//将查询字符串解析为对象
let obj = querystring.parse(str);
console.log(obj);
console.log(obj.keyword,obj.enc);
parse()
解析一个URL为对象,可以获取URL中的各个部分//引入URL模块
const url = require('url');
let str = 'http://www.codeboy.com:9999/product_detail.html?lid=5';
console.log(str);
//将URL解析为对象
let obj = url.parse(str);
console.log(obj);//解析为对象会把url地址分成多部分
console.log(obj.query,obj.pathname);//想找哪个就' . '点哪个,如下图:
fs.statSync(文件路径)
查看文件的状态isDirecotry()
是否为目录isFile()
是否为文件fs.mkdirSync(目录的路径)
创建目录fs.rmdirSync(目录的路径)
删除目录//引入文件系统模块
const fs = require('fs');
/*
//查看文件的状态
let s = fs.statSync('./04');
console.log(s);
//查看文件是否为目录形式
console.log( s.isDirectory() );
//是否为文件形式
console.log( s.isFile() );
*/
//创建目录
fs.mkdirSync('./mydir');
//删除目录
//fs.rmdirSync('./mydir');
带Sync的是同步,不带Sync的是异步
fs.statSync
//引入文件系统模块
const fs = require('fs');
//同步:阻止后边代码的执行
//通过返回值获取结果
let s = fs.statSync('./01_homework.js');
console.log(s);
//如果上述代码单词写错则不会执行'运行结束'
console.log('运行结束');
fs.stat(文件的路径, 回调函数)
//引入文件系统模块
const fs = require('fs');
//异步:不会阻止后边代码执行
//通过回调函数获取结果
fs.stat('./01_homework.js',(err,s)=>{
//err在执行异步的时候可能产生的错误
if(err){
throw err;
}
//s 成功的结果
console.log(s);
});
console.log('运行结束');
//引入文件系统模块
const fs = require('fs');
//同步创建目录
fs.mkdirSync('./123');
//引入文件系统模块
const fs = require('fs');
//异步
fs.mkdir('./index',(err)=>{
if(err){
throw err;
}
});
//引入文件系统模块
const fs = require('fs');
//读取目录(必须有文件夹存在)
let arr = fs.readdirSync('../day02');
console.log(arr);
//引入文件系统模块
const fs = require('fs');
//异步
fs.readdir('../day02',(err,arr)=>{
if(err) throw err;
console.log(arr);
});
writeFileSync(文件的路径,数据)
/ writeFile(文件的路径,数据,回调函数)
*同步
//引入文件系统模块
const fs = require('fs');
//写入文件
fs.writeFileSync('./1.txt','taosang');
*异步
//引入文件系统模块
const fs = require('fs');
//异步写入2.txt
fs.writeFile('./2.txt','tedu.cn',(err)=>{
if(err) throw err;
console.log('写入成功');
});
appendFileSync(文件的路径,数据)
/ appendFile(文件的路径,数据,回调函数)
*同步
//引入文件系统模块
const fs = require('fs');
//同步追加
fs.appendFileSync('./1.txt','taosang');
console.log('追加成功');
*异步
//引入文件系统模块
const fs = require('fs');
//异步追加写入文件
fs.appendFile('./2.txt','涛哥\r\n',(err)=>{
if(err) throw err;
console.log('追加写入成功');
});
\n
改为 \r\n
即可readFileSync(文件路径)
/readFile(文件路径,回调函数)
*同步
//引入文件系统模块
const fs = require('fs');
//读取文件
let data = fs.readFileSync('./1.txt');
//格式为buffer
console.log( data );
//转为字符串
console.log( data.toString() );
*异步
//引入文件系统模块
const fs = require('fs');
//异步
fs.readFile('./stu.txt',(err,data)=>{
if(err) throw err;
console.log(data.toString());
})
unlinkSync(文件的路径)
/ unlink(文件的路径,回调函数)
//引入文件系统模块
const fs = require('fs');
//删除文件
fs.unlinkSync('./1.txt');
//引入文件系统模块
const fs = require('fs');
//删除文件
fs.unlink('./2.txt',(err)=>{
if(err) throw err;
});
existsSync(文件的路径)
存在->true 不存在->false
//引入文件系统模块
const fs = require('fs');
//判断文件是否存在
console.log( fs.existsSync('./mydir1') );
copyFileSync(源文件路径,目标文件路径)
copyFile(源文件路径,目标文件路径,回调函数)
createReadStream()
创建可读取的文件流createWriteStream()
创建可写入的文件流pipe()
管道可以将读取流通过管道添加到写入流on(事件名称, 回调函数)
添加事件,一旦事件触发,会调用回调函数;事件名称是字符串格式//引入文件系统模块
const fs = require('fs');
//创建可读取的文件流,返回对象
let rs = fs.createReadStream('./1.zip');
console.log(rs);
//创建可写入的文件流,创建空文件
let ws = fs.createWriteStream('./2.zip');
//将读取的文件流 通过管道 添加到可写入的文件流
rs.pipe(ws)
//引入fs模块
const fs = require('fs');
//创建可读取的文件流,返回对象
let rs = fs.createReadStream('./1.zip');
//创建可写入的文件流,创建空文件
let ws = fs.createWriteStream('./2.zip');
//将读取的文件流 通过管道 添加到可写入的文件流
rs.pipe(ws)
//添加事件,监听是否有数据流入内存
//on(参数1,参数2) 添加事件
//参数1:是一个字符串,表示事件的名称,固定的
//data 数据流入
//参数2:是一个回调函数,一旦触发事件,调用这个函数,在回调函数中获取流入的数据
let count = 0;//统计数量
rs.on('data',(chunk)=>{
//chunk 获取的分段数据
//console.log(chunk);
count++;//流入一次加1
});
//添加事件:读取结束事件
//一旦读取结束,调用回调函数
rs.on('end',()=>{
console.log(count);
});
express官网网址
:www.expressjs.com.cn
npm i express
也可使用这个命令安装(i 是 install 的简写)
//引入express第三方模块
const express = require('express');
//console.log(express);
//创建WEB服务器
const app = express();
//设置端口
app.listen(8080);
请求的URL
和请求的方法
来做出特定的响应。请求的URL、请求的方法、回调函数
req
请求对象req.url
获取请求的URLreq.method
获取请求的方法req.query
获取查询字符串传递的数据res
响应对象res.send()
设置响应的内容并发送res.redirect()
设置响应的重定向并发送res.sendFile()
设置响应的文件并发送, 文件必须使用绝对路径(__dirname)
以上响应在一个路由中只能调用一次
//引入express第三方模块
const express = require('express');
//console.log(express);
//创建WEB服务器
const app = express();
//设置端口
app.listen(8080);
//添加路由:处理对商品的请求
//请求的URL: /list 请求的方法: get
app.get('/list',(req,res)=>{
//设置响应的内容并发送
res.send('这是商品列表');
});
//练习:添加路由
//请求的URL: /person 请求的方法: get
//响应 ‘这是个人中心
’
app.get('/person',(req,res)=>{
res.send(`
这是个人中心
欢迎回来
`);
});
//添加路由:跳转
//get /study
//跳转到 tmooc
app.get('/study',(req,res)=>{
res.redirect('http://www.tmooc.cn/');
});
//练习:添加路由(get /),跳转到 /person
app.get('/',(req,res)=>{
//同一个服务器下,直接写 /URL
res.redirect('/person');
});
//添加路由(get /index),响应文件1.html
app.get('/index',(req,res)=>{
//响应文件,使用绝对路径
res.sendFile(__dirname+'/1.html');
});
console.log(__dirname);
练习: 创建 03_express.js 和 search.html 。引入express,创建web服务器并设置端口为8080;
添加路由(get /search),响应文件search.html ‘用户搜索’
练习:根据表单的请求添加路由(get /mysearch),响应’搜索成功’
练习:添加路由(get /login),响应文件login.html
练习:用户输入用户名和密码,点击提交;添加对应的路由(post /mylogin),响应‘登录成功’
练习:创建添加到购物车的路由(get /shopping),传递商品的编号lid、购买的数量count、用户的编号uid,最后响应以下内容:
商品的编号:xx
购买的数量:xx
用户的编号:xx
/shopping/30&1&5
新建html文件: search.html
<h2>用户搜索h2>
<form method="get" action="/mysearch">
<input type="text" name="kw">
<input type="submit">
form>
新建js文件: 03_express.js
//引入express
const express = require('express');
//引入查询字符串模块
const querystring = require('querystring');
//创建WEB服务器
const app = express();
//设置端口
app.listen(8080);
//添加路由,响应文件search.html
//get /search
app.get('/search',(req,res)=>{
res.sendFile(__dirname + '/search.html');
});
//练习:根据表单的请求添加路由(get /mysearch),响应'搜索成功'
app.get('/mysearch',(req,res)=>{
//获取请求的URL和请求方法
//console.log(req.url,req.method);
//获取以查询字符串格式传递的数据
console.log( req.query );
res.send('搜索成功');
});
//路由(get /login),响应文件login.html
app.get('/login',(req,res)=>{
res.sendFile(__dirname + '/login.html');
});
//路由(post /mylogin)
app.post('/mylogin',(req,res)=>{
//获取post传递的数据,采用流的方式
//需要使用事件的方式获取
req.on('data',(chunk)=>{
//得到的数据是buffer,转字符串后为查询字符串
console.log(chunk.toString());
//将查询字符串解析为对象
let obj = querystring.parse( chunk.toString() );
console.log(obj);
});
res.send('登录成功');
});
//路由:查看包的详情
//get /package
app.get('/package/:pname',(req,res)=>{
//获取路由传参的数据
console.log(req.params);
res.send('这是包的使用详情');
});
//练习:创建添加到购物车的路由(get /shopping),传递商品的编号lid、购买的数量count、用户的编号uid,最后响应以下内容
app.get('/shopping/:lid&:count&:uid',(req,res)=>{
//获取路由传参的数据
console.log(req.params);
res.send(`
商品的编号:${req.params.lid}
购买的数量:${req.params.count}
用户的编号:${req.params.uid}
`);
});
get传递的数据格式为查询字符串,URL中可见;post传递的方式用流的方式。
URL中不可见,post传递更加安全,通常注册、登录会使用,get传递的速度更快,通常搜索的时候使用
get传递的数据有大小限制,根据不同的浏览器大小不同,范围2~8k之间,post没有大小限制
应用级中间件、路由级中间件、内置中间件、第三方中间件、错误处理中间件
app.use(要拦截的URL,回调函数)
app.use('/list', fn)
app.use(要拦截的URL, 路由器)
app.use( express.static('要托管的目录') );
npm install mysql
insert into 表名 values (值1, 值2,....)
delete from 表名 [where 条件]
delete from 表名 where 列id in (a,b,c)
update 表名称 set 列名称 = 新值 where 列名称 = 某值
select * from 表名
注意: 使用mysql模块时,要开启数据库,不然获取不到
注意:'tedu’数据库是我自己的数据库,你们可以用自己数据库
//引入mysql模块
const mysql = require('mysql');
//创建连接对象
const c = mysql.createConnection({
host: '127.0.0.1', //域名/IP地址
port: '3306', //mysql端口
user: 'root', //数据库的用户名
password: '', //密码
database: 'tedu' //连接成功后要进入的数据库
});
//测试连接
//运行不报错说明测试成功,报错就看单词有没有写错
c.connect();
createConnection()
const c = mysql.createConnection({域名、端口、用户名、密码、数据库});
query(SQL命令, 回调函数)
err 可能产生的错误结果
result 成功的结果
//引入mysql模块
const mysql = require('mysql');
//创建连接对象
const c = mysql.createConnection({
host: '127.0.0.1',
port: '3306',
user: 'root',
password: '',
database: 'tedu'
});
//测试连接
//c.connect();
//执行SQL命令
//异步操作,通过回调函数获取结果
//查询员工表emp中的所有数据
c.query('select * from emp',(err,result)=>{
//err 可能产生的错误结果
if(err) throw err;
//result 成功的结果(SQL命令没有语法错误)
console.log(result);
});
createPool()
const pool = mysql.createPool({域名、端口、用户名、密码、数据库});
比如: select * from emp where ename = 'Tom' or 1; //则会显示所有数据
query('delete from 表名 where 列id=?', [18], (err,result)=>{})
//引入mysql模块
const mysql = require('mysql');
//创建连接池对象
const pool = mysql.createPool({
host: '127.0.0.1',
port: '3306',
user: 'root',
password: '',
database: 'tedu',
//用户的访问量
connectionLimit: 15 //连接池的大小(这句可以省略,因为他默认就是15)
});
//执行SQL命令
//let str = '涛哥" or "1';
let str = 'Tom';
//占位符(?),mysql模块提供的,用于过滤用户提供的数据
pool.query('select * from emp where ename=?',[str/*如果使用 则不会查找出任何数据,这就是防止sql注入*/ ],(err,result)=>{
if(err) throw err;
console.log(result);
});
get 获取资源
delete 删除资源
post 新建资源
put 修改资源
示例 : 添加路由,删除某一个用户资源
app.delete('/v2/users/:uid', (req,res)=>{ })
http://127.0.0.1:8080/v2/users?pno=1&count=10
(pno和count表示页码和每页数据量)
{
"code": 200,
"msg": "登录成功"
}
{
"code": 200,
"msg": "获取成功",
"data": [....]
}