nodejs笔记
node本质- 跨平台js运行环境
nodejs作用
- 开发服务器应用(运行在服务器上)
- 开发工具类应用(Webpack,Vite,Babel)
- 开发桌面端应用(Vscode,postman)
补充知识:
- node xxx文件名可以运行文件
- nodejs中不能使用Dom和Bom的API,可以使用console和定时器API
- nodejs中顶级对象为global,也可以用globalThis访问顶级对象。
用node.js编写api接口
- 1、安装node环境,没有就去下载nodejs, 下载地址
- 2、创建一个node项目, 新建一个目录文件,例node_proxy
- 3、在新建的node项目执行npm init, 文件会生成一个package.json的文件
- 4、安装express框架, 及相关依赖。
npm install express
npm install body-parser
npm install Cookie-parser
npm install cors --save
npm install multer
npm install mysql
- 5、在node项目建一个index.js文件.
res.json这个方法是以json对象的形式返回去,还有以下方法
res.send以页面的方式返回去
res.download以文件的方式返回去,前端请求会下载此文件
/* 引入express框架 */
const express = require('express');
const app = express();
/* 引入cors */
const cors = require('cors');
app.use(cors());
/* 引入body-parser */
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.all('*', function (req, res, next) {
if (!req.get('Origin')) return next();
// use "*" here to accept any origin
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET');
res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
// res.set('Access-Control-Allow-Max-Age', 3600);
if ('OPTIONS' == req.method) return res.send(200);
next();
});
app.get('/', (req, res) => {
res.send('<p style="color:red">服务已启动</p>');
})
app.get('/api/list', (req, res) => {
res.json({
code: 200,
message: '成功',
data: {
list: []
}
});
})
/* 监听端口 */
app.listen(3000, () => {
console.log('listen:3000');
})
- 6、启动接口: node index.js
- 7、在前端则使用http://localhost:3000/api/list 去访问这个接口
到了这里想必你们已经发现问题了,我每次改动一下都要重新跑程序,这不符合人体工程学,说的一点没错,我无法容忍,你萌呢?
想必你们在前面也发现了pageage.json里有这么一句话
scripts的作用就是自己定义脚本命令,在这下面定义的所有命令都可以使用npm run xxx来运行,可以省略run。里面运行的应该是node index.js才对,但是这里我们使用了一个插件,hotnode,这个插件可以让你的node程序热更新,要全局安装这个插件,不然找不到命令。
npm install -g hotnode
然后我们就可以npm start运行我们的程序了,所有基于node的程序跑起来都是两步,npm install,安装所有插件,npm start运行程序,如果跑不起来,那么这个项目一定不是一个好项目,我通常如此告诫我的弟子,我们一定要站在巨人的肩上。
post不支持浏览器直接访问,这个时候要用postman软件
依然符合我们的预期。
可以把路径改为/login,/test进行尝试,这里就不再演示了。
也可以试试app.all方法,这个方法支持所有请求方式,不必每个请求都写好几遍了。
想必大家已经想到了,我要做登录拦截难道每个接口里都要写一遍吗。
答案是当然不用的,接口的第一个参数可以用正则表达,我们这么写:
我们使用来匹配所有路径,这个时候请求test,会先经过,被拦截返回了**,
我们可以在内部判断来进行操作:
如果未登录,返回未登录,否则,继续向下匹配,回调函数接收三个参数,最后一个是next,继续向下执行,路径一定要写在最上面,不然会先被test捕捉到,test没有执行next,就会捕捉不到请求。
这时候就可以设置login的值来看路径localhost/test下的返回值了。
那么有参数的情况呢,我们先引入一下中间件,如果没有安装可以先npm安装
接下来我们请求一下
?后面的表单参数会放到req.query里,路径上的参数会放到req.params里,json参数会放到req.body里,可以任意选择一种参数传递即可,路径以:开头表示此路径作为参数的意思。
前后端联调的时候经常碰到跨域的问题,我们可以使用cors插件解决,
以上提到的跨域和参数都可以自己进行处理,利用路径自己提取参数,在*路径的请求的请求体req里自己加上跨域允许的header,但我希望你们可以使用插件,保证代码的简洁性,同时
我经常告诉我的弟子,我们一定要站在巨人的肩上。
好了,接下来我们开始连接数据库,从数据库里拿一条数据出来返回给前端。
引入mysql插件,我们先在mysql里新建一个表students,存入以下数据:
然后使用mysql插件连接数据库
option里都是连接数据库的基本配置,更多参数可以查看文档,我们请求一下localhost/login看看
真的返回了我们存在数据库的数据,我好激动啊,大业终于完成了。
是的,conn.query就是执行一条sql语句,在回调函数里返回结果。
结果可以用构造函数封装,这样就不用每次都写一推没用的字段了。
如果你在此处这样做:
那么这个不妥的,第一次没有问题,第二次不行了,说是关闭了数据库无法继续查询,因为connect()并不能重连数据库,你需要重新建立一条新连接,所以不建议使用conn.end()断开数据库。
如果莫名其妙断了呢,我们就需要就重连机制,断了数据库会触发error事件,我们这样处理:
监听error事件,如果err.code返回了以上字符,那么我们就重新发起连接,直到连接成功。
做到这里,想必大家已经想到了,这是单线程的,并发量高的时候会不会顶不住,会的,所以我们要上连接池。
连接池与连接相似,做以下处理:
建立连接池比连接多了几个参数,这里罗列了常用的三个,其它参数可以查看文档。这个时候我们使用连接池处理请求。conn.release()的意思是释放连接池的意思,用完就要释放给别的请求使用,也可以直接使用连接池,具体区别我还不知道,我猜应该是直接使用连接池就是这个线程专门为这个请求服务,不用别的也不释放,可以用于常用接口,可以减少取连接池的操作。
做到这里我们大部分工作已经做完了,想必大家一定又想到了什么,我如果有一千个接口,难道要在一个文件里写一千个吗。
这当然是不妥的,比较难维护,所以我们要拆分模块,使用express.Router()这个api。
我们将连接数据库的文件单独抽离
导出常用的pool,Result,router,app模块,然后在子模块:
然后在入口:
看看是不是简洁多了,要注意一点,引入的子模块要放到全局监听的下面,不然又会无法匹配到,app.use的第一个参数代表下发到那个目录,内部子模块的/相当于app.use的第一个参数,接下来请求一下/和/login试试吧。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!