Node.js是一个调用内置ApI并且基于Chrome V8引擎的js运行环境,之前自己在本地总结了一些零散的只知识点,今天整合一下发出来。
官网地址: https://nodejs.org/zh-cn/
①基于 Express 框架(http://www.expressjs.com.cn/),可以快速构建 Web 应用
②基于 Electron 框架(https://electronjs.org/),可以构建跨平台的桌面应用
③基于restify框架(http://restify.com/),可以快速构建 API 接口项目
④读写和操作数据库、创建实用的命令行工具辅助前端开发、etc…
下载链接:https://nodejs.org/en/
查看版本号:node –v
学习路线:JavaScript 基础语法 + Node.js 内置 API 模块(fs、path、http等)+ 第三方 API 模块(express、mysql 等)
命令:node js文件名
终端快捷键:
①使用 ↑ 键,可以快速定位到上一次执行的命令
②使用 tab 键,能够快速补全路径
③使用 esc 键,能够快速清空当前已输入的命令
④输入 cls 命令,可以清空终端
定义:把复杂问题简单化,分成一个个小问题。编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块
把代码进行模块化拆分的好处:
定义:由Node.js官方提供,如fs、http、path
// 引用内部模块 const fs = require('fs'); // 文件读取 fs.readFile('../files/test-fs.txt', 'utf-8', (err, results) => { if (err) return console.log(err.message);// 错误信息err null console.log(results); }) // 文件写入 fs.writeFile('../files/test-fs.txt', 'Node.js', 'utf-8', (err) => { if (err) return console.log(err.message); console.log('写入文件成功!'); })
注意点
定义:拼接绝对路径
const fs = require('fs'); const path = require('path'); const fpath = path.join(__dirname, '/../files/test-fs.txt'); fs.readFile(fpath, 'utf-8', (err, results) => { console.log(__dirname); console.log(path.basename(fpath, '.txt')); console.log(path.extname(fpath)); if (err) return console.log(err.message); console.log(results); }) // test-fs // .txt // Node.js
定义:Node.js提供创建web服务器
// 导入http模块 const http = require('http'); //创建web服务器实例 const server = http.createServer(); //绑定request事件,监听客户端请求 server.on('request', (req, res) => { let str = `路径 ${req.url} 方法 ${req.method}`; console.log(str); // 向客户端发送中文前,设置响应头 res.setHeader('Content-Type', 'text/html;charset=utf-8'); res.end(str); }) //启动服务器 server.listen(80, () => { console.log('http://127.0.0.1'); })
const fs = require('fs'); const http = require('http'); const path = require('path'); const server = http.createServer(); let fpath = ''; server.on('request', (req, res) => { if (req.url === '/') { fpath = path.join(__dirname + '/../files/clock/index.html'); console.log(__dirname); console.log(fpath); } else { fpath = path.join(__dirname + '/../files/clock' + req.url); } fs.readFile(fpath, 'utf-8', (err, results) => { if (err) res.end('404 not find'); res.end(results); }) }) server.listen(80, () => { console.log('http://127.0.0.1'); })
定义:用户自定义的js模块
//引入本地文件 const custom = require('./01-node.js的使用');
注意:自定义模块开头必须有./ …/
定义:由第三方提供,使用前需要下载
//下载外部导入 const moment = require('moment');
npm i nodemon -g
代替node使用nodedmon,每次修改内容不需要重启服务器,自动监听
模块作用域定义:和函数一致,当前模块定义的方法、变量,只能在当前模块访问,防止变量污染
暴露:通过module.exports或者exports暴露出去,使用 require() 方法导入模块时,导入的结果,永远以module.exports 指向的对象为准
定义: 一次加载缓存,从缓存加载 ,内置模块加载优先级MAX
包:概念像node.js的第三方模块,包是基于内置模块封装出来的,提供了更高级、更方便的 API,极大的提高了开发效率
npm: 包管理工具
// npm i moment const moment = require('moment'); const date = moment().format('YYYY-MM-DD HH:mm:ss'); console.log(date);//2022-09-10 10:43:24
包的版本号是以“点分十进制”形式进行定义的,总共有三位数字,例如 2.24.0
其中每一位数字所代表的的含义如下:
第1位数字:大版本
第2位数字:功能版本
第3位数字:Bug修复版本
版本号提升的规则:只要前面的版本号增长了,则后面的版本号归零。
npm i comment@2.22.2
//安装包 npm i moment //安装全局包 npm i 包名 -g //安装包到开发阶段到devDependencies npm i 包名 -D //安装所有依赖包 npm install //卸载包 npm uninstall moment //查看已经安装的局部包 npm ls //查看全局安装的包 npm ls -g
查看包命令:https://blog.csdn.net/qq_41664096/article/details/121797260
//查看当前npm镜像 npm config get registry //nrm镜像工具,安装为全局镜像 nrm ls //切换镜像 nrm use taobao
一个规范的包,它的组成结构,必须符合以下 3 点要求:
发布包到npm上
资源:
Express:基于Node.js http进一步封装,更加高级的Web开发框架
对于前端程序员来说,最常见的两种服务器,分别是:
//导入包 const express = require('express'); //创建服务器 const app = express(); app.get('/user', (req, res) => { res.send({ 男: '18', age: 28 }); }) app.post('/user', (req, res) => { res.send('post请求'); }) app.get('/', (req, res) => { //req.query ?name=zs&age=18 这种数据 //http://127.0.0.1?name=zs&age=18 console.log(req.query); }) app.post('/:id', (req, res) => { //动态匹配参数 console.log(req.params); }) //启动服务器 app.listen(80, () => { console.log('http://127.0.0.1'); })
定义:通过路径暴露文件,省去文件路径的描写
const express = require('express'); const app = express(); //托管静态资源,不需要访问 app.use('/public', express.static('../files/clock')); app.listen(80, () => { console.log('http://127.0.0.1'); })
推荐VScode插件:postcode
Express 的中文官网: http://www.expressjs.com.cn/
定义:客户端与服务器映射关系
//导入包 const express = require('express'); //创建服务器 const app = express(); app.get('/user', (req, res) => { res.send({ 男: '18', age: 28 }); }) app.post('/user', (req, res) => { res.send('post请求'); }) //启动服务器 app.listen(80, () => { console.log('http://127.0.0.1'); })
为了方便对路由进行模块化的管理,Express 不建议将路由直接挂载到 app 上,而是推荐将路由抽离为单独的模块。
将路由抽离为单独模块的步骤如下:
创建路由对象
const express = require('express');//导入包 const router = express.Router();//创建路由对象 //绑定路由规则 router.get('/user/list', (req, res) => { res.send('user list message'); }) router.post('/user/add', (req, res) => { res.send('user add message'); }) //向外导出路由对象 module.exports = router;
使用路由对象
const express = require('express'); const app = express(); const router = require('./11-模块化路由'); app.use(router); app.listen(80, () => { console.log('http://127.0.0.1'); })
中间件:与路由处理函数不同,必须包含next参数
const express = require('express'); const app = express(); //全局中间件的简化形式 app.use((req, res, next) => { console.log('正在使用全局中间件'); next(); }); app.get('/',(req, res) => { res.send('Get message'); }) app.listen(80, () => { console.log('http://127.0.0.1'); })
注意
多个中间件共享req,res,上游设置好,下游的中间件/路由使用
中间件定义先后顺序执行
局部生效的中间件,定义在
app.get('/',中间件,(req, res) => { res.send('Get message'); })
路由之前调用中间件
next()函数不能忘,后面不用写内容
const express = require('express'); const app = express(); //全局中间件 app.use((req, res, next) => { console.log('全局中间件'); next(); }) //局部中间件 function mw(req, res, next) { console.log('局部中间件'); next(); } app.get('/', mw, (req, res) => { res.send('server is visting'); }) app.listen(80, () => { console.log('http://127.0.0.1'); })
定义:绑定到 express.Router() 实例上的中间件
定义:捕获项目错误,防止出错,在所有路由之后定义
const express = require('express'); const app = express(); app.get('/', (req, res) => { throw new Error('服务器出错'); res.send('server is visting'); }) //全局中间件 app.use((err, req, res, next) => { console.log('Error!' + err.message); res.send('Error!' + err.message); next(); }) app.listen(80, () => { console.log('http://127.0.0.1'); }) //Error!服务器出错
const express = require('express'); const app = express(); // express.json()解析JSON请求体 app.use(express.json()); //解析application/x-www- app.use(express.urlencoded({ extended: false })); app.post('/user', (req, res) => { console.log(req.body); }) app.post('/book', (req, res) => { console.log(req.body); }) app.listen(80, () => { console.log('http://127.0.0.1'); }) // http://127.0.0.1 // { name: 'zs', age: 18 } // [Object: null prototype] { name: '西游记' }
const express = require('express'); const app = express(); const parser = require('body-parser'); app.use(parser.urlencoded({ extended: false })); app.post('/book', (req, res) => { console.log(req.body); }) app.listen(80, () => { console.log('http://127.0.0.1'); })
注意:Express 内置的 express.urlencoded 中间件,就是基于 body-parser 这个第三方中间件进一步封装出来的。
封装中间件
const querystring = require('querystring'); function parsebody(req, res, next) { let str = ''; req.on('data', (result) => { str += result; }) req.on('end', () => { const body = querystring.parse(str); req.body = body; next(); }) } module.exports = parsebody;
测试中间件
const express = require('express'); const app = express(); const parsebody = require('./14-自定义中间件'); app.use(parsebody); app.post('/user', (req, res) => { res.send(req.body); console.log(req.body); }) app.listen(80, () => { console.log('http://127.0.0.1'); })
const express = require('express'); const app = express(); const router = require('./15-接口问题'); app.use(router); app.listen(80, () => { console.log('http://127.0.0.1'); })
const express = require('express'); const apiRouter = express.Router(); apiRouter.get('/user', (req, res) => { const query = req.query; res.send({ status: 0, msg: 'GET 请求成功', data: query }); }) module.exports = apiRouter;
apiRouter.use(express.urlencoded({ extended: false })); apiRouter.post('/user', (req, res) => { const body = req.body; res.send({ status: 0, msg: 'POST 请求成功', data: body }); })
https://blog.csdn.net/qq_42931285/article/details/119852294
https://zhuanlan.zhihu.com/p/135454697
概念:由Http响应头构成,决定浏览器是否阻止js代码获取资源,在服务器端配置
//只允许特定的域名访问、*代表全部 res.setHeader('Access-Control-Allow-Origin', 'http://www.baidu.com'); //配置请求头信息 res.setHeader('Access-Control-Allow-Headers', 'Content-Type,X-Custom-Header'); //配置请求头方法 * 代表全部 res.setHeader('Access-Control-Allow-Methods', 'GET,POST,DELETE,PUT');
概念:只支持GET请求
定义:组织、存储、管理数据的仓库
select * from users where id>1 and id <5
insert into users(username,password) values('jack','666')
update users set password='666666' where username='jack'
delete from users where id=9
//引入mysql const mysql = require('mysql'); //建立数据库连接 const db = mysql.createPool({ url: '127.0.0.1',//数据库IP地址 user: 'root',//账号 password: '123456',//密码 database: 'test_db'//操作哪一个数据库 });
const queryStr = 'select * from users'; db.query(queryStr, (err, results) => { if (err) return console.log(err.message); console.log(results); }) PS E:\FED\js\node.js\node.js—资料\day总复习\code> node .\18-mysql操作.js [ RowDataPacket { id: 1, username: 'zz', password: '123', status: 0 }, RowDataPacket { id: 2, username: 'ls', password: 'abc', status: 0 }, RowDataPacket { id: 4, username: 'jony', password: '456', status: 0 } ]
const user = { username: 'superman', password: 'jknad' }; const insertStr = 'insert into users set ?'; db.query(insertStr, user, (err, results) => { if (err) return console.log(err.message); if (results.affectedRows == 1) { console.log('插入数据成功'); } }) //插入数据成功
const user = { id: 10, username: 'super', password: '123456' }; const updateStr = 'update users set ? where id=?'; db.query(updateStr, [user, user.id], (err, results) => { if (err) return console.log(err.message); if (results.affectedRows == 1) { console.log('更新数据成功'); } })
const deleteStr = 'delete from users where id=?'; db.query(deleteStr, 10, (err, results) => { if (err) return console.log(err.message); if (results.affectedRows == 1) { console.log('删除成功'); } })
const deleteStr = 'update users set status=1 where id=?'; db.query(deleteStr, 10, (err, results) => { if (err) return console.log(err.message); if (results.affectedRows == 1) { console.log('删除成功'); } })
概念:服务端在后台拼接html页面,发送给客户端,不需要ajax
特点:
概念:后端提供API接口,前端通过ajax调用接口
特点:
不谈业务场景而盲目选择使用何种开发模式都是耍流氓
概念:通过不同的手段(验证码、密码、人脸、指纹...),认证客户的身份
Cookie:存储在浏览器不超过4KB字符串,键值对形式存储
核心:会员卡+pos机认证