1、什么是express?
express是一个专门用来做服务器功能的模块;它本身是一种编程框架,能快速搭建服务器,提升编程效率;
框架是一整套解决方案,把已有的功能进行了简化,添加了之前没有的功能,最终目的是提升工作效率
express网址是https://www.expressjs.com.cn/
2、路由
路由是express中最重要的部分之一,主要功能是封装功能接口;
客户端发来请求,服务器端根据客户请求的url确定响应方法,在express中称为定义了一个路由;
常用的方法有get,post ,put,delete ;但是用的比较多的是get和post,用的比较少的是put和delete;这四种方法中get和delete相像,put和post相像
路由方法:对应的是客户端请求的方法,get\post\put\delete
路由路径:定义了请求的目标
路由句柄:是一个请求处理函数
1、请求对象request
express的处理请求消息的异步函数中,第一个形参是请求消息的描述对象,从此对象中可以读取请求消息的数据
app.get('/',function(req,res){
req.methond//请求方法
req.url//请求url
req.headers//请求头部
req.body//请求主体
req.query//查询字符串数据对象
req.params//路由参数对象
})
request对象中的方法与属性:
req.app:当callback为外部文件时,用req.app访问express的实例
req.baseUrl:获取路由当前安装的URL路径
req.body / req.cookies:获得「请求主体」/ Cookies
req.fresh / req.stale:判断请求是否还「新鲜」
req.hostname / req.ip:获取主机名和IP地址
req.originalUrl:获取原始请求URL
req.params:获取路由的parameters
req.path:获取请求路径
req.protocol:获取协议类型
req.query:获取URL的查询参数串
req.route:获取当前匹配的路由
req.subdomains:获取子域名
req.accepts():检查可接受的请求的文档类型
req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
req.get():获取指定的HTTP请求头
req.is():判断请求头Content-Type的MIME类型
2、响应对象response
express的处理请求消息的异步函数中,第二个形参是请求消息的响应对象,设置向客户端输出的响应数据
app.get('/',function(req,res){
res.stats(200)//状态码
res.type('json')//修改content-type类型
res.set(header,value)//设置响应头信息
res.send('response body')//发送响应信息
res.sendFile('filepath/filename')//发送文件
res.json(obj)//发送json响应
res.redirect("path")//重定向地址
})
response对象的方法与属性:
res.app:同req.app一样
res.append():追加指定HTTP头
res.set()在res.append()后将重置之前设置的头
res.cookie(name,value [,option]):设置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
res.clearCookie():清除Cookie
res.download():传送指定路径的文件
res.get():返回指定的HTTP头
res.json():传送JSON响应
res.jsonp():传送JSONP响应
res.location():只设置响应的Location HTTP头,不设置状态码或者close response
res.redirect():设置响应的Location HTTP头,并且设置状态码302
res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
res.send():传送HTTP响应
res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
res.set():设置HTTP头,传入object可以一次设置多个头
res.status():设置HTTP状态码
res.type():设置Content-Type的MIME类型
3、路由-get方法
使用express中的路由方法get()可以处理用户使用get方法发送的请求信息
app.get("/",function(req,res){
...............
})
该方法对应的前端页面表单信息提交的get方法,该方法不安全,提交的数据会以明文的形式拼接到页面的URL中
4、路由-post方法
使用express中的路由方法post()可以处理用户使用post方法发送的请求信息
app.post('/',function*(req,res){
res.on('data',(data)=>{
var body=queerystring.parse(data.toString())
})
})
同理该方法对应的是表单中的post提交方法,使用该方法进行数据交还,相对get来说数据安全性更高
5、路由-put方法
put请求在项目中常用来表示处理修改数据库资源的操作,所以,使用方式和post方式基本一致,使用的是流传递参数的方式。处理流传递方式获取数据使用req.on('data',(chunk)=>{....})方式,或者引入body-parser第三方中间件,使用req.body方式。
app.put('/v1/emps/update',(req,res)=>{
pool.query('update emp set ? where eid=?',[req.body,req.body.eid],(err,result)=>{
if(err)throw err
console.log(result)
if (result.affectedRows) {
res.send({code:200,msg:'员工修改成功'})
}else{
res.send({code:201,msg:'员工修改失败'})
}
})
})
6、路由-delete方法
delete请求在项目中用来表示处理删除数据库数据的操作,使用方式和get方式基本一致,使用的路由传参或者是查询字符串,所以当需要获取请求的数据的时候使用的是req.query或者是req.params方式。
app.delete('/v1/emps/del/:eid',(req,res)=>{
pool.query('delete from emp where eid = ?',[req.params.eid],(err,result)=>{
if (err) {throw err}
console.log(result)
if(result.affectedRows){
res.send({code:200,msg:'员工删除成功'})
}else{
res.send({code:201,msg:'员工删除失败'})
}
})
})
7、路由-all方法
对所有请求进行处理;使用express中的路由方法all()可以处理客户端提交的所有请求信息
app.all('/',function(req,res){
................
})
3、路由参数传递
1、路由传参
客户端在提交请求信息时,express不仅可以使用传统的字符串查询方式,express还允许在url中包含参数
app.get('/weather/:days',(req,res)=>{
//在这里可以使用req.params获取days的参数,使用的时候参数直接加载路径中无需使用a=b的形式
console.log(req.params)
})
这种方式称为路由传参;参数在URL中拼接,使用请求对象request的params属性获取URL中的参数
注意:路由传参,参数必须存在,不允许传递空值
//根据用户ID删除用户
router.delete("/del/:uid",(req,res,next)=>{
let uid=req.params.uid-0
let sqlStr="delete from xz_user where uid = ?"
pool.query(sqlStr,[uid],(err,result)=>{
datadle.delhandle(req,res,next,err,result)
})
})
2、查询字符串传参
查询字符串传参指的是正常的get查询方式,get查询方式会想所有的查询信息通过符号【?】【&】【=】拼接起来,这种方式就是查询字符串方式
app.get('/weather',function(req,res){
。。。。。。。。
})
查询字符串:http://127.0.0.1:8080/mysearch?keyword=手机
//根据ID查询数据
router.get("/sel",(req,res,next)=>{
let obj=req.query
let sqlStr="select * from xz_user where uid = ?"
pool.query(sqlStr,[obj.uid-0],(err,result)=>{
datadle.selhandle(req,res,next,err,result)
})
})
3、流的方式传递参数
流传递参数的方式就是指的post或者是put方式,这两种都属于流方式传递,但是put一般是用来提交文件的,所以一般流传参指的是post方法
流传递参数是无法直接在URL中获取到的,这时候想要获取数据,需要使用到对请求对象绑定监听函数【data】:
req.on('data', (chunk)=>{
chunk获取的分段数据,格式为buffer,转字符串后为查询字符串,需要解析为对象
})
这种方法比较复杂,每一种情况都需要对应的去编辑获取方法;可以使用第三方中间件进行body部分的解析【body-parser】Let obj = req.body
router.post("/signin",(req,res,next)=>{
let sqlStr="select uname from xz_user"
let obj=req.body
let sqlStr1="insert into xz_user set ?"
pool.query(sqlStr,(err,result)=>{
if(err){
console.log(err)
next()
return
}
// console.log(result)
// res.send(result)
for (let i = 0; i < result.length; i++) {
if(obj.uname==result[i].uname){
res.send({code:401,msg:"用户名已存在"})
return
}
if(obj.phone==result[i].phone){
res.send({code:402,msg:"电话号码已注册"})
return
}
}
pool.query(sqlStr1,[obj],(err,data)=>{
datadle.addhandle(req,res,next,err,data)
})
})
})
4、路由器
·1、创建路由器
在大型项目中,路由的数量可能达到超乎想象,所以将所有路由都写到一个文件中,不便于后期维护已经处理;所以路由器就是将不同的路由,格局逻辑模块的方式分表划分到不同的文件中并用特定的对象加以管理,这样的对象就称为路由器
express.Router路由器,是一种可以同时挂在多个路由的对象,而且一般有着相同的路由器地址前缀
const express=require('express')
const router=express.Router()
router.get('/index',(req,res)=>{
res.send('这是测试首页')
})
router.get('/login',(req,res)=>{
res.send('这是测试登录页')
})
router.get('/list',(req,res)=>{
res.send('这是测试列表')
})
router.get('/details',(req,res)=>{
res.send('这是测试详情页')
})
router.get('/outer',(req,res)=>{
res.send('这是测试退出页')
})
router.get('/center',(req,res)=>{
res.send('这是测试中心页')
})
module.exports=router
2、使用路由器
const express = require('express')
const router=require('./day0322ExpressRouter.js')
const app=express()
let server = app.listen(8080,()=>{
let host=server.address().address
let port=server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})
app.use('/router',router)//挂载路由器
挂载路由器,添加前缀'/router'区分以其他模块可能出现的重复现象