web 开发之node.js
前言:从零开始介绍node.js长篇预警(建议收藏),在看这篇博客之前你需要了解下mysql数据库和javascript 这两样我的博客都有介绍。接下来就请各位指教了,感谢!
安装好node js 后 window+R cmd 后 输入 node -v 可以查看 nodejs 版本 也表示安装nodejs成功 直接 输入node可以运行nodejs 命令
1.Node.js概述
简单的说 Node.js 就是运行在服务端(即后端)的 JavaScript。
(1)对比JS和Node.js
JS是运行在客户端浏览器,存在多款浏览器,存在代码兼容性问题;
Node.js是运行在服务器端,只有一种环境,不存在兼容性问题。
两者都有内置对象、自定义对象,不同的宿主对象
JS用于开发浏览器端的交互效果,Node.js用于服务器端的开发,数据库的操作、其它服务器的访问..
(2)node.js特点及应用场景
单线程运行逻辑,适合做基于社交网络的大规模的web应用,例如微博、抖音...
2.node.js 的对象(部分)
(1)global
检测一个变量或者函数是不是全局下的,如果是可以通过global来访问 (注意:
Node.js下每一个文件都是在一个模块作用域下,变量和函数都是局部的,有效的防止污染全局。
) js相对node.js的global 的全局对象是 window
(2)console
console.log(1); //日志
console.info(2); //消息
console.warn(3) ; //警告
console.error(4); //错误
console.time('canshu1') //开始计时
console.timeEnd('canshu1') //结束计时
开始计时和结束计时两者的参数要保持一致。
(3)process对象 进程
process.arch 查看CPU的架构
process.platform 查看当前的操作系统版本
process.version 查看当前Node.js的版本
process.pid 查看当前进程的编号
process.kill() 结束指定编号的进程
(4)Buffer对象 缓冲区、缓冲器,位于内存中,临时存储数据的区域,常用于保存网络传输的资源,例如在线视频..
Buffer.alloc(5, 'abcde') 创建buffer为5个字节,并存储数据,1个汉字占3个字节。可以用
String() / toString() 将buffer转为字符串
3.模块
模块是一个独立的功能体,每一个文件都是模块他们之间是引入和被引入的关系
模块分为自定义模块、核心模块、第三方模块
require: 是一个函数,用于引入其它的模块 如引入文件系统模块:
var fs = require('fs')
module.exports: 当前模块导出的内容,默认是一个空对象,如果要导出哪些内容,只需要放入到对象中。(可以用于导出自定义的模块)
模块下的两个局部变量
__dirname: 当前模块的绝对目录
__filename: 当前模块的绝对目录和模块名称
console.log(__filename);
console.log(__dirname);
模块的分类:
(1)文件形式的引入:
require('./ziDingYi.js') 用于当前目录下引入自定义模块 (目录可以自己更改,这里为了便于理解就引用的当前目录)
require('querystring') 用于引入官方提供的核心模块
(2) 目录形式的引入:
require('./ziDingYi') 首先会到目录下package.json文件中寻找main属性对应的文件,如果找不到则会自动寻找index.js文件对其引用。
require('fs') 会到当前目录下的node_modules目录中寻找fs目录,如果找不到会一直往上一级的node_modules目录中寻找 用于引入第三方模块
4.包和 npm
包(package):就是第三方的模块,是目录形式的模块如(mysql等)
npm:管理包的工具,包括下载安装、上传、卸载、升级... nodejs安装的时候自动附带安装
可以在命令窗口 键入 npm -v 查看npm的版本号
常用的npm 命令有
npm init -y 初始化项目说明文件package.json
npm config get registry 获取当前下载仓库的地址
npm config set registry https://registry.npm.taobao.org 设置下载仓库地址为淘宝镜像(改为国内下载)
npm install 包的名称 下载安装指定的包,会自动将包放入node_modules目录中,如果node_modules目录不存在会自动创建;会在package.json中记录下载安装的包名称和版本号;会生成文件package-lock.json,用于记录依赖的包的版本号。
npm install 自动安装package.json和package-lock.json中记录的已经安装的包的名称和版本号。
npm run 快捷名称 自动到package.json中,scripts下对应的名称并运行(前提是要先自行设置并保存好)如图
npx 在npm5.2以后自动安装的工具(所以安装较高版本的node.js 比较好)
npx -p node@8 node 文件名称 在使用nodejs运行文件之前,先去下载指定的nodejs版本,然后再运行文件;运行完以后再把下载的nodejs删除。(这样有效的避免了重复下载不同版本的node.js,在一个版本可运行其他版本的node.js大大提高了工作效率)
5.查询字符串模块(querystring)
查询字符串是浏览器端向web服务器传递数据的一种方式,位于URL中如
parse() 将查询字符串解析为对象,可以得到传递的数据
const querystring = require('querystring'); var str = querystring.parse('https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%8D%9A%E5%AE%A2&fenlei=256&rsv_pq=a167532500056e60&rsv_t=4268GA7vo5%2BGdEItQc5kgZOrMGHT%2FsfWlhWJcswkRReOt7LvQ9VfmQFEKkU&rqlang=cn&rsv_dl=tb&rsv_enter=1&rsv_sug3=6&rsv_sug2=0&rsv_btype=i&inputT=1291&rsv_sug4=1955'); console.log(str);
得到一个对象可以通过属性调用
6.URL模块
URL: 统一资源定位,互联网上任何资源都有对应的URL,通过这个URL可以找到该资源。
http://www.baidu.com:9999/product_details.html?lid=5
协议 域名/IP地址 端口 文件的路径 查询字符串
parse() 将URL解析为对象,可以获取各个部分
7.定时器模块
(1)一次性定时器
开启 var timer=setTimeout(回调函数, 间隔时间); //当间隔时间到了,调用一次回调函数,单位是毫秒。 清除 clearTimeout(timer);
(2)周期性定时器
开启 var timer=setInterval(回调函数, 间隔时间); //每隔一段时间,调用一次回调函数 清除 clearInterval(timer)
(3)立即执行的定时器
开启 var timer=setImmediate( 回调函数 ) 清除 clearImmediate(timer)
process.nextTick( 回调函数 ) 无法清除
两者都是立即执行的定时器,都是在事件队列的最前边,process.nextTick比setImmediate更先执行
所有定时器都会在事件队列里排队,其他代码优先运行
8.文件系统模块 fs
服务器端的文件分为文件形式和目录形式
//引入fs模块 const fs=require('fs'); //1-------------------------------------------------查看文件状态 //同步:通过返回值获取结果 var s=fs.statSync('../day02'); //console.log( s.isFile() );//是否为文件形式 console.log( s.isDirectory() );//是否为目录形式 console.log(s); //异步:通过回调函数来获取结果 fs.stat('./01.js',(err,s)=>{ //err 可能产生的错误结果 //s 成功获取到的结果 if(err){ throw err; } console.log(s); }); //2------------------------------------.-----------------读取目录 //同步 //var arr=fs.readdirSync('../day02'); //console.log(arr); //异步 readdir fs.readdir('../day02',(err,arr)=>{ if(err){ throw err; } console.log(arr); }); //3.--------------------------------------------------------创建目录 //fs.mkdirSync('./mydir'); //异步创建mydir2 mkdir fs.mkdir('./mydir2',(err)=>{ if(err) throw err; console.log('目录创建成功'); }); //4---------------------------------------------------------.移除目录 //fs.rmdirSync('./mydir'); fs.rmdir('../day02',(err)=>{ if(err) throw err; }); //5.---------------------------------------------------------写入文件 //fs.writeFileSync('./1.txt','ran'); fs.writeFile('./2.txt','tedu',(err)=>{ if(err) throw err; }); // 如果文件不存在,先创建文件然后写入数据 如果文件已经存在,会覆盖写入数据 //6.---------------------------------------------------------追加写入 fs.appendFile('./3.html','WEB前端2011\n',(err)=>{ if(err) throw err; console.log('文件写入成功'); }); //如果文件不存在,先创建文件然后写入数据 如果文件已经存在,会在文件的末尾追加写入数据 //7.----------------------------------------------------------读取文件 var data=fs.readFileSync('./stu.txt'); //buffer data得到的是buffer形式的对象 console.log(data); //转字符串 console.log( String(data) ); //使用异步方法读取3.html fs.readFile('./3.html',(err,data)=>{ if(err) throw err; console.log( String(data) ); }); //8.------------------------------------------------------------删除文件 //同步 //fs.unlinkSync('./1.txt'); //异步 //fs.unlink('./.txt',(err)={ if(err) throw err; }); //9.----------------------------------------------------------检测文件是否存在 var res=fs.existsSync('../day02'); //异步形式已经弃用 console.log(res); 反回 true 或者 false //拷贝文件 fs.copyFileSync('./3.html','./mydir/3.txt'); //copyFileSync(源文件路径, 目标文件路径) / copyFile(源文件路径, 目标文件路径, 回调函数)
9.同步和异步
同步:会阻止后续代码的执行,先执行完当前的再往后执行,通过返回值来获取结果。
异步:不会阻止后续代码的执行,在一个独立的线程执行,通过回调函数来获取结果
10.文件流
//引入fs模块 const fs = require('fs'); //创建可读取的文件流 var rf = fs.createReadStream('./1.zip'); //创建可写入的文件流 var wf = fs.createWriteStream('./mydir/2.zip'); //写入的文件名可以改但类型最好不要改 //把读取的流通过管道添加到写入流 rf.pipe(wf);
可以通过事件监听,是否有数据流入
//data 数据流入事件,固定的 //一旦事件被触发,通过回调函数来获取数据 var count=0;//用于记录读取的段数 rs.on('data',(chunk)=>{ //on(事件名称, 回调函数) 用来添加事件 //chunk 获取到的分段数据 //console.log(chunk); //得到的chunk对象千万不要转字符串否则容易死机 //每读取一段加1 count++; }); //console.log(count); //监听读取结束事件 rs.on('end',()=>{ console.log(count); //查看总共有多少条数据流 });
10.http协议 是客户端和web服务器之间的通信协议 (这里只做简单的介绍)
(1)通用的头信息 (这些信息可以通过浏览器检查 查看到)
Request URL: 请求的URL,请求的资源
Request Method: 请求的方法, get/post/delete/put...
Status Code: 响应的状态码
1**:服务器端接收到了请求,还没做出响应
2**:成功的响应
3**:响应的重定向,会跳转到另一个URL
4**:客户端请求错误
5**:服务器端错误
(2)响应的头信息 response
Content-Type:响应的内容类型, html对应 text/html 还有编码设置
Location:设置跳转的URL
(3)请求的头信息 request
(4)请求的主体
可有可无,用于设置传递数据
11.node.js中的http模块 用于创建web服务器
const http=require('http'); //创建web服务器 const app=http.createServer(); //设置端口 app.listen(8080); //添加事件,监听是否有请求 app.on('request',(req,res)=>{ //req 请求的对象 console.log(req.url,req.method); //req下两个常用的方法可以获取url和请求方式 //res 为响应的对象 /* //设置响应的状态码和头信息 res.writeHead(200,{ //若状态码为404 可以不用添加头信息(回掉函数) //设置内容类型和编码 'Content-Type': 'text/html;charset=utf-8' }); //设置响应的内容 res.write('<h1>这是内容</h1>'); //结束并发送响应 res.end(); //设置响应的状态和跳转的URL res.writeHead(302,{ Location: 'http://www.tmooc.cn' }); //结束并发送响应 res.end(); */
通过不同的url反回不同的网页如下:
const http=require('http'); const fs=require('fs'); const app=http.createServer(); app.listen(8080); //添加事件 app.on('request',(req,res)=>{ //根据请求做出响应 if(req.url==='/login'){ res.writeHead(200,{ 'Content-Type':'text/html;charset=utf-8' }); res.write('<h1>这是登录的网页</h1>'); }else if(req.url==='/study'){ res.writeHead(302,{ Location: 'http://www.tmooc.cn' }); }else if(req.url==='/index'){ //读取1.html文件 var data=fs.readFileSync('./1.html'); //把读取到的数据响应 res.write(data); }else{ res.writeHead(404); res.write('not found'); } //结束并发送响应 res.end(); });
可见引用http模块创建web服务器端比较麻烦于是便有了比较方便的express第三方模块
npm install express //下载express框架
12.express框架 express是一款基于Node.js平台,快速、开放、极简的WEB开发框架
框架是一整套的解决方案,已有的功能进行封装简化,添加了一些没有功能。
//引入express包 const express=require('express'); //console.log(express); //可以看到express本身是一个function 且含有很多function //创建web服务器 const app=express(); //设置端口 app.listen(8080); //可见比http模块简单
要想设置看到客户端和服务端的请求和响应还需要另一个概念:路由
(2)路由 :服务器端根据请求的方法和请求的URL来做出特定的响应,例如注册有注册的路由,登录有登录的路由... 路由,由请求的方法、请求的URL、回调函数组成。
//引入express包 const express=require('express'); //console.log(express); //可以看到express本身是一个function 且含有很多function //创建web服务器 const app=express(); //设置端口 app.listen(8080); //登录的路由 //请求的方法:get 请求的URL:/login app.get('/login',(req,res)=>{ res.send('<h1>这是登录的网页</h1>'); // res.send 设置响应内容并发送 并结束响应
}); //添加注册的路由 //请求的方法:get 请求的URL: /reg //响应'<h2>请注册</h2>' app.get('/reg',(req,res)=>{ res.send(` <h2>请注册</h2> 请输入用户名 `); }); //路由 //请求的方法:get 请求的URL:/study app.get('/study',(req,res)=>{ //响应的重定向 res.redirect('http://www.cnblogs.cn'); }); //添加首页的路由 //请求的方法:get 请求的URL:/ //跳转到登录的路由 /login app.get('/',(req,res)=>{ res.redirect('/login'); // res.redirect() 设置响应的重定向,跳转到另一个URL
}); //路由 //请求的方法:get 请求的URL:/index app.get('/index',(req,res)=>{ //响应文件并发送 res.sendFile(__dirname+'/1.html'); //设置响应的文件并发送,使用文件的绝对路径
res.sendFile()
});
上面多介绍了响应的方法 下面为请求的方法
//引入查询字符串模块
const querystring=require('querystring');
const app=express();
app.listen(8080);
//响应搜索页面get /search app.get('/search',(req,res)=>{ res.sendFile(__dirname+'/search.html'); }); //根据表单的请求创建对应的路由(get /mysearch),响应'搜索成功' app.get('/mysearch',(req,res)=>{ //console.log(req.url,req.method); //req.url req.method获取的请求的URL,请求的方法 console.log(req.query); //req.query获取请求的查询字符串形式的数据 res.send('搜索成功'); }); //路由 get /login app.get('/login',(req,res)=>{ res.sendFile(__dirname+'/login.html'); }); //根据表单请求创建路由 post /mylogin app.post('/mylogin',(req,res)=>{ //获取post传递数据,以流的方式 //通过事件的方式,一旦数据流入,自动获取 req.on('data',(chunk)=>{ //console.log( chunk ); var data=String(chunk); console.log(data);//查询字符串 //引入查询字符串模块,解析为对象 var obj=querystring.parse(data); console.log(obj); }); res.send('登录成功'); }); //添加路由(get /package),响应'这是包的使用详情' app.get('/package/:pname',(req,res)=>{ // "/:pname" url的形式参数 实参在浏览器中传入可以是多个
console.log(req.params); //req.params获取路由传参形式的数据
res.send('这是包的使用详情'); });
总结:路由中获取数据的方式:
以URl传递的一个URL的字符串 通过 req.query获取数据 其 格式为对象
以流方式传递来的数据,通过事件方式获取数据
req.on('data',(chunk)=>{ //得到的chunk格式为buffer,转字符串后为查询字符串,需要解析为对象 String(chunk) //再通过其属性就可以获得对应的属性值了 })
通过路由传参得到的数据 需要对应形参来接收
app.get('/package/:pname',(req,res)=>{ // “/:pname” :形参 req.params // //获取路由传参形式的数据 格式为对象 });
虽然有了路由可见简化很多代码 但是当遇到url重名时却无可奈何 于是便有了路由器
(3)路由器 其作用是把同一模块下的所有路由放到一起,最终挂载到web服务器,而且可以个同意个模块下所有的URL添加统一的前缀 这也是一个中间件(后面再详细介绍)
创建路由代码如下
const express= require('express'); //引用express框架,因为路由器是express下的一个方法 const u= express.Router(); //创建路由器 u.get('/list',(req,res)=>{ //添加url以及反回的内容 res.send('这是用户列表'); }); module.exports=u //导出路由器
为了便于理解再创建一个路由器
const express=require('express'); //与上面的相比是两个不同的js文件 const p=express.Router(); p.get('/list',(req,res)=>{ res.send('这是商品列表') }); module.exports=p; //module.exports后面是等于一个对象的但是这里只写了一导出对象 就直接省略了{}
路由器创建好了接下来是调用路由的中间件
const express=require('express'); //引入express框架啊模块 const shangpingRouter=require('./router/p.js'); //这里写的路径是上面路由器文件的路径 const yonghuRouter = require('./router/u.js'); //导入另一个路由器 const app = express(); //创建服务器 app.listen(8080); //设置端口号 app.use('/v1/product',shangpingRouter); //将路由器挂载到服务器上 app.use('/v1/user',yonghuRouter); //相当于是一个路由级的中间件,当
开启服务器后添加对应的后缀名后就可以访问到对应的网页了
上面提到了中间件接下来讲讲中间件是怎么回事
13.中间件 可以按照URL拦截客户端对服务器端的请求,中间件可以分为应用级(自定义)中间件,路由级中间件,内置中间件,第三方中间件,错误处理中间件 这里分别举例其中的代表性操作 详情可以查看其官网
(1)应用级中间件 也称自定义的中间件是一个函数
const express=require('express'); const app=express(); app.listen(8080); function fun(req,res,next){ if(req.query.name!=='root'){ res.send('无法访问') //满足条件做出响应 }else{ next() }; //不满足条件执行路由 } app.use(‘/list’,fun) //拦截URL为list时启用中间件 调用回掉函数注意有三个参数 app.get('/list',(req,res)=>{ res.send('欢迎登陆'); });
其中的回调函数可以根据需求写不同规则
(2)路由级中间件 也即是路由器的使用 app.use(URL,引入的路由器) 见上面 的路由器有详细介绍
(3)内置中间件 这是express提供好的,可以直接拿来用 如静态资源请求即是托管静态资源,当浏览器端请求静态资源,服务器端不需要创建路由,而是由让浏览器端自动的到指定的目录下查找。
const express=require('express'); const app= express(); app.listen(8081); app.use(express.static('./public')); //托管静态资源到public目录
在地址栏输入对应的静态资源文件名就会自动到public目录下寻找并在网页上呈现出来(前提一定要有对应的文件)
public下有1.html文件
(4)第三方中间件 属于第三方模块的形式 需要下载安装 这里以body-parser中间件为例
npm install body-parser 下载安装
body-parser中间件 用于将所有的post请求的数据(流)解析为对象 有点类似于querystring模块但比其简单些
//下载好body-parser模块后 const express = require('express'); const bodyParser=require('body-parser'); //引入模块 const app=express(); app.listen(8082); //将所有的post请求数据解析为对象 app.use(express.static('./public')); //引入提前写好的html文件(html内设置数据请求方式为post) app.use(bodyParser.urlencoded({extended:false})) //方法括号里的内容可以不写但会报错 ,不影响整体的代码 app.post('/myblog',(req,res)=>{ var data=req.body; //得到html的请求数据对象 res.send('响应成功'); //可以响应上面的数据内容 });
到此中间件的介绍 这里只是极少举例 各个中间件的常见基础使用方式
14.mysql 模块 属于第三方模块需要下载
npm install mysql
下载好后就可以引用mysql 进一步操作数据库了
const mysql = require('mysql'); const c =mysql.createConnection(); //创建连接对象 //c.connect() //执行连接数据库 用于测试 c.query('select * from 表 where id=2',(err,result)=>{}) //这句话会默认连接数据库,执行sql语句,通过回调函数可以返回结果
上面的SQL语句中可以在条件处引入客户端的请求信息代码如下
const express=require('express'); const mysql =require('mysql'); const app=express(); const c=mysql.createConnection({ host:'localhost', user:'root' , port:'3306', password:'', database:'yaoshiyongdeshujuku' }); app.get('/zidingyi/:id',(req,res)=>{ //字符串传参 var data = req.params.id; c.query(`select * from where id=${data}`,(err,result)=>{ //用模板字符串将外面的变量引入 if(err) throw err; res.send(result); }); });
但是上面的代码容易产生SQL注入,若是在字符串传参的时候在最后加‘or 1=1 ’就会把所有的数据响应 为了避免上面的情况我们可以用数组过滤字符串
//在上面的代码中做如下修改 c.query(`select * from where id=?`,[id],(err,result)=>{
这样一来可以有效的防止sql注入 因为数组会过滤掉非表中的数据
接下来便是关于连接池的知识
上面连接数据库的方式mysql.createConnection({})虽然实现了业务需求但是创建连接时,只有一个连接,它会一直持续到关闭它(或者它被mysql服务器关闭).我们可以通过引用传递它并重新使用它,也可以按需创建和关闭连接.
而创建的连接池是存储连接的地方.当您从池请求连接时,您将收到当前未使用的连接或新连接.如果您已经处于连接限制,它将等待连接可用,然后才能继续.这些池化连接不需要手动关闭,它们可以保持打开状态并且易于重复使用.
我们使用的连接方式完全取决于我们的业务需求,创建连接池的方式和上面的也差不多
const mysql = require('mysql') const pool=mysql.createPool({ host:'localhost', user:'root', port:'3306', password:'', database:'shujukumingzi', connectionLimit:'15' //设置连接数量不宜过大 可以不用设置这行有默认值 }) pool.query('sql语句',()=>{}) //使用连接池操作数据库
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
想必学到这里我们已经感受到每次代码的改动都要运行命令窗口在到浏览器运行查看,这这。。。样搞开发已经不是头秃而是键盘秃了,各位看官觉得呢?反正你们也不点赞,我就当你们键盘没秃,下面的东东可以不用看了,哼!!
这时我们就要引入接口和一种比较流行的接口设计风格(规范)RESTful
先来聊聊接口 我们知道 URL:对应请求的资源
接口就是
https ://i.cnblogs.com /posts/edit;postId=14169722
协议 域名/IP地址 端口 路由 查 询字符串
RESTful接口规范其中路由的格式
/v1/zidingyi/1
/v1/zidingyi?s1=5000
/v1/users/3
/v1/users/checkuname
/版本号/资源/资源的编号
请求的方法 这里知识一部分其实还有很多就不一一列举了
插入数据 post
删除数据 delete
修改数据 put
查询数据 get
返回结果 json对象
{"code":"状态码", "msg":"消息内容"}
{"code":200, "msg": data: [] }
上图:
15.ApiPost 一款用于测试接口的工具 ,有了这个就不用为了个post请求建heml文件传数据再开运行等等一顿影响开发效率的事了。
这是下载地址给各位大佬奉上https://pan.baidu.com/s/14znej-KdtDQS-0xjpxluDw软件登陆好后的使用方法如下:
软件准备好了接下就开始介绍数据库操作及服务器代码结合该软件的使用吧 ## 不过这一切的前提是下面所用到模块都要安装好哟!
就以一个简单的项目为例吧先看看项目的目录结构
这是文件的图片
基本结构已经知道了接下来是代码了
首先是路由器user.js
const epxpress= require('express'); //优先导入express模块 const u = express.Router(); //调用express模块下的router方法创建路由器 u.post('/reg',(req,res)=>{ //简单创建个路由,并做出响应 res.send('ok') }); module.exports=u; //导出 路由器
然后是服务器app.js引入路由器操作
const express = require('express');
const bodyParser = require('body-parser'); //引入body-parser模块供后面使用
const app = express(); app.listen(8080); //创建服务器和端口
app.use(bodyParser.urlencoded({extended:false})) //避免报错 const rRouter = require('./router/user.js') //导入路由器 app.use('/v1/users',rRouter); //用中间件添加前缀并使用
再然后是在同级目录下创建连接池pool.js
const mysql = require('mysqsl'); const pool = mysql.createPool({ host:-----, port:----, user:----, password:-----, database:------, //这些内容介绍mysql已经介绍过就不赘述了 connectionLimit:--- }); module.exports= pool; //导出连接池
连接池创建好之后就是在user.js中导入 加上下面的代码即可
const pool = require('../pool.js') //在上一级目录中找到pool.js文件
接下来就是介绍通过路由器对数据库进行增删改查的代码 一切以上面已有的代码为基准 毕竟重复的代码太过累赘
首先是对数据库的增加内容在user.js下进行
u.post('/zeng',(req,res)=>{ var data = req.body; //由于app.js中已经导入了body-parser模块 这里可以直接使用body方法 ,导入有Apipost软件传来的body对象 var num = 400; for(var i in data){ num++; if(data[i]){ //这里可以做判断传来的值是否为空做出相应的响应,后面我就略过了 res.send(code:num,msg:i+'值不能为空'); return; } } pool.query('insert into biao set ?',[data],(err,result)=>{ if(err){ console.log(err); //打印出可能的错误 并做出响应 res.send(code:500,msg:'服务器端错误!') //之后的介绍中这里是重复我将略过 return; } res.send(code:200,msg:'添加信息成功') //添加成功后做出的响应 }); });
在命令窗口运行app.js后对应aipPost 上的软件操作如下:
接下来是 删 代码如下
u.delete(‘/delete/:uid’,(req,res)=>{ var data = req.params.uid; //判断是否为空这里的代码我就不赘述与上面类似 pool.query('delete from biao where id=?',[data],(err,result)=>{ //输入删除的sql语句 if(err) throw err //写法与上面类似这里不赘述 if(result.affectedRows){ //affectedRows为result对象的属性,若找到对应的id并删除成功后的值为1 res.send({code:200,msg:'删除成功'}); }else{ res.send({code:201,msg:'删除失败,未找到该id'}) } }); });
对应apipost软件操作如图:
接下来是 更改 的代码:
u.put('/update/:uid',(req,res)=>{ var data =req.params.uid; var data2 = req.body; pool.query('update biao set ? where uid=? ',[data2,data],(err,result)=>{ if(err) thorw err; if(result.affectedRows){ res.send({code:200,msg:'修改成功',data:result}) }else{ res.send({code:201,msg:'修改失败(可能是编号不存在)'}) } }); });
对应apipost软件操作如图:
接下来是 查 普通查询我就不介绍了说说分页查询吧!代码奉上:
u.get(‘/cha’,(req,res)=>{ var ye = req.query.pno; //得到通过字符串传参得到的参数 var shu = req.query.count; if(!ye||ye==0){ //如果为0或空设置默认值 ye=1; } if(!shu){ //设置默认值 shu =5; } var start = (ye-1)*shu; //已经隐式转换为数值为limit做准备 shu = parseInt(shu); //强制转为数值 pool/.qeury('select * from biao limit ?,?',[start,shu],(err,result)=>{ //注意limit后面空格必须 if(err) throw err if(!result[0]){ //得到的result为数值如有结果不为空 res.send({code:200,msg:'查询成功',data:result}); }else{ res.send({code:201,msg:'未查询到目标,请输入正确的开始值'}); } }); });
最后是apiport软件的操作:
到此就可以写下简单的项目了
到这node.js就介绍的差不多了 编写不宜多多点赞转发感谢给位! 有不足之处还望指教!
教你如何上传代码至码云传送门https://www.cnblogs.com/CIBud/p/14203569.html