express响应
express响应在回调函数的res参数上,express兼容原生HTTP模块的方法,同时也自己封装了一些新的方法。
HTTP模块原生方法:
javascript
const express = require('express')
const app = express()
app.get('/test',(req, res)=>{
//HTTP模块原生方法
res.statusCode = 404 //设置响应报文的状态码
res.statusMessage = 'error' //设置响应报文的状态信息
res.setHeader('error_flag',true) //设置响应报文的响应头
res.write('request error') //设置响应报文的响应体
res.end('!')
})
app.listen(3002,()=>{
console.log('server start!')
})

expresss提供的新方法:
基础方法
javascript
const express = require('express')
const app = express()
app.get('/test',(req, res)=>{
//express封装响应方法
res.status(500) //设置状态码
res.set('error_flag_express',true) //响应头
res.send('error') //响应体
})
app.listen(3002,()=>{
console.log('server start!')
})

express支持连写方法,效果是一样的:
javascript
app.get('/test',(req, res)=>{
//express封装响应方法
//express支持连续设置
res.status(404).set('error_flag2',true).send('error')
})
express除了对基础方法进行了封装,还提供了其他的封装方法,这里记录几个比较常用的方法:
其他方法
1.重定向
当满足当前请求匹配时,该请求会重定向到指定URL,该请求状态返回30x(重定向状态码),并且在响应体的Location字段中记录重定向要跳转到的地址,然后自动进行跳转
javascript
app.get('/test',(req, res)=>{
//express封装的其他响应方法
//重定向
//当满足当前请求匹配时,该请求会重定向到指定URL,该请求状态返回30x(重定向状态码),
//并且在响应体的Location字段中记录重定向要跳转到的地址,
//然后自动进行跳转
res.redirect('http://www.test2.com')
})

2.下载
res.download(文件绝对路径)
当请求满足匹配规则时,会自动下载文件绝对路径对应的文件:
javascript
app.get('/test',(req, res)=>{
//express封装的其他响应方法
//下载
res.download('./package.json')
})

访问对应URL,表现为下载操作:


3.JSON响应
res.json(需要转换为JSON格式传输的数据)
用于把对应的数据以JSON形式进行相应。
javascript
app.get('/test',(req, res)=>{
//express封装的其他响应方法
//响应JSON数据
res.json({
test:'data'
})
})


4.响应文件
如果是想把某个文件中的内容作为响应体响应给浏览器(而不是下载),可以使用该方法。
res.sendFile(文件路径)
index.js:
javascript
app.get('/test',(req, res)=>{
//express封装的其他响应方法
//响应文件内容
res.sendFile(__dirname+'/test.html')
})
test.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
test data
</div>
</body>
</html>
访问对应网址:

中间件
中间件(Middleware)其实是一个回调函数。因此也叫中间件函数。
中间件函数像路由回调一样,可以访问请求对象、响应对象。
中间件用于使用函数封装公共操作,简化代码。
中间件分为全局中间件、路由中间件、静态资源中间件。
中间件其实就是请求在服务器端被处理之前加一层拦截,如果满足中间件的匹配,请求会先进中间件进行处理,然后再进对应的路由函数。
全局中间件
每一个请求到达服务器之后都会执行全局中间件函数。
考虑这样一种场景,如果想记录每个请求到LOG文件,这个功能就可以通过中间件实现。
如果不使用中间件,当前也能实现该功能,但是需要在每个路由的回调函数中添加同样的代码:
javascript
const express = require('express')
const fs = require('fs')
const path = require('path')
const app = express()
app.get('/home',(req, res)=>{
let {url, ip} = req
fs.appendFileSync(path.resolve(__dirname,'./1.log'),`${url} ${ip} \r\n`)
res.send('home page')
})
app.get('/admin',(req, res)=>{
let {url, ip} = req
fs.appendFileSync(path.resolve(__dirname,'./1.log'),`${url} ${ip} \r\n`)
res.send('admin page')
})
app.listen(3002,()=>{
console.log('server start!')
})
通过添加中间件,可以减少代码量。
全局中间件基础语法:
中间件通过中间件函数定义,中间件函数具有三个参数req(请求对象) res(响应对象) next(函数内部方法,进行后续中间件的回调函数,或者路由的回调函数,如果不调用next,则方法会一直停在这里)。
定义中间件之后,通过app.use(函数名)使用该方法,即可给每个路由都添加中间件。
例子:
javascript
const express = require('express')
const fs = require('fs')
const path = require('path')
const app = express()
function recordMiddleware(req, res, next){
let {url, ip} = req
fs.appendFileSync(path.resolve(__dirname,'./1.log'),`${url} ${ip} \r\n`)
next()
}
app.use(recordMiddleware)
app.get('/home',(req, res)=>{
res.send('home page')
})
app.get('/admin',(req, res)=>{
res.send('admin page')
})
app.listen(3002,()=>{
console.log('server start!')
})
路由中间件
路由中间件具有路由判断,只有满足条件的请求才会走中间件的回调函数。
比如,考虑这样一种场景,我们想在访问/admin、/search页面时,进行权限校验,只有携带了身份权限校验信息code,并且code等于指定值的情况下,才允许访问。如果不携带参数,则进行无权限的提示。
与上一个例子类似,如果我们在各自路由的回调函数中写逻辑,当然也可以实现功能,但是这样代码会比较冗余。
路由中间件的基本语法:
与全局中间件类似,路由中间件也需要声明中间件函数,只不过不使用app.use进行全局调用,而是作为参数放在对应的路由规则里。
例子:
javascript
const express = require('express')
const app = express()
function accessMiddleware(req, res, next){
if(req.query.code === 'test'){
next()
}else{
res.send('没有权限')
}
}
app.get('/home',(req, res)=>{
res.send('home page')
})
app.get('/admin',accessMiddleware , (req, res)=>{
res.send('admin page')
})
app.get('/search',accessMiddleware ,(req, res)=>{
res.send('search page')
})
app.listen(3002,()=>{
console.log('server start!')
})

效果:



静态资源中间件
静态资源:内容长时间不发生改变的一些资源。
静态资源目录/网站根目录:当网站访问服务器时,去寻找的服务器根目录。
静态资源中间件用于设置访问静态资源时的目录。
**基础语法:**express.static(文件夹路径)
想要让这个设置生效,还需要app.use:
app.use( express.static(文件夹路径) )
例子:
javascript
app.use(
express.static(__dirname+'/public')
)


除了可以使用静态资源中间件实现对静态资源的请求以外,也会自动对请求资源的类型进行设置,也就是说,请求资源的content-type会根据资源的类型自动配置,而不需要代码手写。
注意事项:
1.index.html是默认打开的资源
也就是说,如果配置了静态资源中间件,访问网站原始路径时,也就是说访问/时,其实访问的是index.html。
2.如果静态资源与路由规则同时匹配,取决于代码的顺序
如果我的项目中既有index.html的静态资源,也有app.get('/',...)的路由规则,此刻是谁先被匹配呢?这取决于代码的顺序,在匹配时,匹配是自上而下的,也就是说,从代码的顶端开始匹配,如果app.use(静态资源中间件)在前面,就会先匹配静态资源,反之,如果app.get在前面,就会匹配路由规则。
3.路由响应动态资源,静态资源中间件响应静态资源
一般来说,路由规则响应一些动态资源,比如搜索结果;而静态资源中间件规则响应一些静态资源。
**实际应用:**在实际开发中,前端开发好之后,对自己的项目进行打包,然后把文件交给服务器端,服务端把文件放在根目录下,这样访问网址时,显示的就是前端页面了。
