nodejs笔记
js:1995 Netscape ,运行在客户端
nodejs:2009 Ryan dahl , V8引擎,运行在服务器端的开发环境
1. Node.js 内置全局对象
1.1 global 对象
- 可以查看一个变量或者方法是否是全局的 global.a (交互模式下 )
- 在node.js下,脚本文件不是全局作用域下,防止了全局污染
- JS的全局叫window,在JS下 脚本文件是全局,存在全局污染
1.2 console对象
console.log()
打印日志- console.info() 打印消息
- console.warn() 打印警告
- console.error() 打印错误
- console.time(‘label’);console.timeEnd(‘label’);
1.3 process对象
- porcess.arch 查看CPU架构
- process.platform 查看操作系统
- process.version 查看node.js版本
- process.pid 查看进程pid
- process.kill(pid) 杀掉进程
1.4 Buffer
临时在内存中存储数据
Buffer.alloc(5,'abcde');
// 将数据保存到缓冲区Buffer.toString()
//读取缓冲区转为字符串
2. 全局函数
2.1 一次性定时器
let timer=setTimeout(callback,time);
开启定时器clearTimeout(timer);
清除定时器
2.2 周期性定时器
let timer=setInterval(callback,time);
开启定时器clearInterval(timer);
清除定时器
3. 模块
每一个模块都是一个独立的功能体
每一个脚本文件就是一个模块
3.1 模块分类
- 自定义模块
- 核心模块
- 第三方模块
以路径开头 | 不以路径开头 | |
---|---|---|
文件形式 | require(‘./circle.js’) | |
目录形式 | require(‘./02_ran’) 首先寻找02_ran目录下的package.js中”main”属性对应的文件 如果找不到默认为index.js | require(‘ran’) 默认从下至上寻找node_modules文件夹>ran文件夹 package.json>main属性 |
用法:
引入:let obj=require(‘文件路径’);
导出:module.exports={ };
console.log(__dirname); //获取当前模块的绝对路径
console.log(__filename);//绝对路径+模块名称
3.2 包和npm
npm: node package manager,用于管理包的工具模块,包括包的下载,升级,卸载,上传
npm init -y
//初始化项目npm install 包的名称
//安装包npm install
//根据package.json配置安装包npm config get registry
//获取当前仓库路径npm config set registry https://registry.npm.taobao.org
//设置仓库路径到淘宝镜像
npx:选择使用不同的nodejs版本运行文件
- npx -p node@版本号 node 文件名
3.3 querystring模块(查询字符串)
- querystring.parse();
3.4 URL模块
统一资源定位
http://www.codeboy.com:9999/product_details.html?lid=1
协议 域名/ip 端口 文件路径 查询字符串
URL模块——用于操作URL的模块
- const url=require(‘url’);
- url.parse(str);
- 方式一:
没有斜杠,跳转到和自己同目录下的页面
- 方式二:
单斜杠加前有一点,跳转到和自己同目录下的layout页面 总结:方式一和方式二效果是相同的。
- 方式三:
单斜杠,跳转到整个网站根目录下的
- 方式四: 两点加单斜杠,跳转到上一级目录
- 方式五: 多个两点加单斜杠连续用,每一次“../”往上跳转一级,有几个“ ../”,就向上跳几级(ps:我以前错以为只能写一个“../”)
- 方式六:全路径方法
3.5 timer模块
- setImmediate(callback) //安排在 I/O 事件的回调之后立即执行的 callback。process.nextTick(callback)会比setImmediate(callback)队列更靠前执行
3.6 fs模块
文件系统包括目录形式和文件形式。
同步操作
- fs.mkdirSync(‘./新建文件夹’) //创建目录
- fs.rmdirSync(‘./新建文件夹’) //移除空文件夹
- fs.statSync(‘文件名’); // 查看状态
- fs.writeFileSync(…)
- fs.appendFileSync(…)
- fs.readFileSync(…)
- fs.unlinkSync(…) //删除
- fs.existsSync(…); //检测文件或目录是否存在
- fs.copyFileSync(path,goalpath); //拷贝
异步操作
- fs.mkdir(…)
- fs.rmdir(…)
- fs.stat(path,callback); // callback(error,success);.
- success.isFile() //是文件
- success.isDirectory(); //是目录
- fs.writeFile(…);
- fs.appendFile(…)
- fs.readFile(…)
- fs.unlink();
大文件的复制
fs.createReadStream('path').pipe(fs.createWriteStream('path'));
- 同步和异步(day03)
同步:阻塞后续代码执行,通过返回值获得结果
异步:在一个独立的线程执行,不会阻塞后续代码执行,通过回调函数获得结果
5. http协议
是浏览器和web服务器之间的通信协议
5.1 general 通用头信息
Request url: 要请求的资源
request method: 请求的方法, post/get/delete/
status: 状态码
- 5xx(服务器错误)
- 4xx(请求错误)
- 3xx (重定向)
- 2xx (成功)
- 1xx(临时响应)
表示临时响应并需要请求者继续执行操作的状态代码。
5.2 request headers
5.3 response headers
- Location: http://www.baidu.com/ //重定向地址
- Content-Type:响应的内容类型
5.4 请求主体
只有传递数据时才会有
6. Http模块
1 | const http = require('http'); |
7. Express 框架(day04)
基于node.js平台 快速 开放 极简的WEB开发框架
下载安装 npm install express
7.1 路由
const express=require(‘express’); //express初始化 const app=express(); app.listen(80); | |||
---|---|---|---|
//路由 app.get(‘/login’,(req,res)=>{ res.send(‘这是登陆的网页‘) }); |
app.get(‘/study’,(req,res)=>{ res.redirect(‘https://www.baidu.com'); }); | app.get(‘/‘,(req,res)=>{ res.sendFile(__dirname+’/index.html’); }); | app.get(‘/index’,(req,res)=>{ res.redirect(‘/‘); }); |
传递的方式 | 格式 | 路由接收的方式 |
---|---|---|
查询字符串 | http://127.0.0.1:8080/mysearch?keyword=手机 | req.query格式为对象 |
流的方式 | 不可见 | 通过事件 req.on(‘data’, (chunk)=>{ chunk接收的分段数据,格式为buffer,转字符串为查询字符串,需要使用查询字符串模块解析为对象 }) |
路由传参 | http://127.0.0.1:8080/package/ran | app.get(‘/package/:pname’,(req,res)=>{ //pname 形参 req.params 接收数据,格式为对象 }) |
7.2 路由器(day05)
?
:问号之前的一个字符只能出现零次或一次。例如,路由路径'/ab?cd'
路径匹配端点acd
或abcd
。+
:加号之前的一个字符至少出现一次。例如,路径路径'/ab+cd'
匹配端点abcd
、abbcd
、abbbcd
,等。*
:星号可以替换为任意字符串。例如,路由路径'ab\*cd'
匹配端点abcd
、abXcd
、abSOMErandomTEXTcd
,等。()
:将一个字符串视为一体以执行?
、+
、*
操作。例如。'/ab(cd)?e'
将对(cd)
进行匹配,将匹配到abe
和abcde
。
模块 | 引用模块 |
---|---|
module.exports= r;//导出路由器对象 | app.use(‘/user’,userRouter); //将用户的路由器挂载到web服务器下,并添加前缀’/user |
//创建路由器对象 const r=express.Router(); //添加路由 r.get(‘/list’,(req,res)=>{ res.send(‘ 这是用户列表‘) }); |
const userRouter=require(‘./user.js’); |
7.3 中间件
用于拦截对web服务器中路由的请求,可以做出响应
分为自定义中间件,路由级中间件,内置中间件,第三方中间件,错误处理中间件
自定义中间件(应用级中间件)
本质上就是一个回调函数 app.use(url,callback); callback(req,res,next);
路由级中间件
内置中间件
静态资源: html、css、js、图片、视频····· 托管静态资源: 浏览器端要请求静态资源,服务器端不需要创建路由,而是让浏览器自动的到指定位置寻找 若同级托管目录下有相同资源,会找到第一个后停止 app.use(express.static('./public'));
第三方中间件
body-parser
7.4 Express-generator
安装 express-generator
1 | npm install express-generator -g |
8. 正则表达式(day05)
正则表达式完整视频 https://pan.baidu.com/s/1IgYS8oGBrRgZQropPUTnoA ;提取码:nbx3
字符串正则相关函数的用法总结 https://pan.baidu.com/s/1Rvqr-5UI7NxoxArdgxyRhg ;提取码:08yj
- [\u4e00-\u9fa5] 中文字符集
- * 可有可无 多了不限
- ?可有可无 最多一次
- + 最少一次 多了不限
支持正则的字符串方法:
let i=str.search(/正则/i);
从头开始查找第一个符合正则的位置
返回值:没找到:-1 ,找到了返回第一个字符的下标
let arr=str.match(/正则/);
用正则去匹配str中第一个符合要求的字符串
如果找到,则返回关联数组,数组中包含匹配正则的字符串和该字符串的下标 [“0”,”字符串内容”,”index”,索引];
如果找不到返回null
拓展知识:js只有一种数组:关联数组
默认只找第一个,解决方法 /正则/g ,一但加 g 就不能获得索引位置,只能获得字符串
既查找关键词内容,又查找关键词位置,用reg.exec()实现
str.replcae()
简单替换
`str=str.replace(/正则/g,"新值");` /g 全部替换
高级替换
str=str.replace(/正则/g,function(keywords){ return 根据keywords不同,返回不同的值 }); 例: 去除字符串中的前后空格
str=' you can '.replace(/^\s*|\s*$/g,""); //'you can'
例: 将字符串中的单词首字母大写
str='you can you up'.replace(/\b\w/ig,(k)=>k.toUpperCase()); // 'You Can You Up'
str=str.splite(/正则/);
强调: 不用加g
例:
1
2
3let str= ' <li>1</li><li>2</li><li>3</li><li>4</li> <li>5</li> ';
str=str.replace(/^(\s*<li>)|(<\/li>\s*)$/ig,'');
let arr=str.split(/<\/li>\s*<li>/);
9.MySQL 模块 (day06)
mysql | 连接池 |
---|---|
const connnection=mysql.createConnection({ host:’127.0.0.1’, port:’3306’, user:’root’, password:’liwenzhe’, database:’tedu’ }); //连接 connnection.connect(); | const pool=mysql.createPool({ host:’127.0.0.1’, port:3306, user:’root’, password:’liwenzhe’, database:’tedu’, connectionLimit:20 }); //创建连接池 |
connnection.query(‘DELETE FROM emp where ename=”李文哲”‘, //异步 (err,res)=>{ //插入 //err可能产生的错误 //成功的结果 if(err) throw err; console.log(res); }); | pool.query(‘SELECT * FROM emp’,(err,result)=>{ if(err) throw err; console.log(result); }); |
9.1 防止注入攻击
例:let name='李文哲" or "1'; pool.query('DELETE FROM emp where name="'+name+'"',callback); //注入攻击 // DELETE FROM emp where name="李文哲" or "1"; |
---|
// ? 代表占位符,第二个参数会被自动过滤,过滤完替换占位符 // pool .query(‘SELECT * FROM emp WHERE ename=?’,[name],callback); |
9.2 使用对象作为参数
let obj={ eid:null, ename:'东子',sex:1,salary:5000,birthday:'1976-5-29'};
//缺少的会填充默认值 //属性名必须与sql表的列一致
//执行sql命令直接插入
1 | pool.query('INSERT INTO emp SET?',[obj],(err,result)=>{ |
10. 接口
10.1 数据接口:后端给前端提供的资源
REST : 一种接口风格,行业内认同的风格
RESTful : 是基于REST风格的接口
url
http://127.0.0.1:8080/v1/emps 版本号 资源名称 http://127.0.0.1:8080/v1/emps/3 传递的数据(获取单个资源)
http://127.0.0.1:8080/v1/users/login
对资源的操作请求方法
对资源的操作 post 新建资源(插入数据) delete 删除资源 put 修改资源 get 获取资源
过滤数据
http://127.0.0.1:8080/v1/emps?pno=1&count=10
返回结果
- 状态码
- 对象/数组(json)
工具: ApiPost,PostMan
10.2 错误处理
错误中间件,写到所有路由之后
① if(err) {next(err);return;} |
---|
② app.use((err,req,res,next)=>{ res.sendStatus(500);}); |