1、express.static快速托管静态资源
express:快速、开放、极简的Web开发框架。(npm第三方包,提供快速创建web服务器便捷方法)
Express中文官网
(1) express快速创建web网站服务器以及api接口服务器
// 1、导入express
const express = require('express')
// 2、创建web服务器
const app = express();
// 3、调用app.listen(端口号,启动成功后回调函数),启动服务器
app.listen(80,()=>{
console.log('express server running at http://127.0.0.1');
})
(2) 监听GET和POST请求
// 参数1:客户端请求url地址
// 参数2:请求对应的处理函数 req请求对象,res响应对象
app.get('请求url',function(req,res){
...
})
app.post('请求url',function(req,res){
...
})
(3) 把内容响应给客户端
通过res.send()方法,把处理好的内容,发送给客户端:
app.get('/user',(req,res)=>{
res.send({name:'zs',age:20,gender:'男'})
})
app.post('/user',(req,res)=>{
res.send('请求成功!')
})
(4)获取url中携带的查询参数
通过req.query对象,访问客户端通过查询字符串的形式,发送服务器参数:
app.get('/',(req,res)=>{
console.log(req.query)
})
(5) 获取URL中的动态参数
通过req.params对象,可以访问到URL中,通过:匹配到动态参数
app.get('/user/:id',(req,res)=>{
console.log(req.params)
})
(6)托管静态资源
express.static()创建静态资源服务器;按照引入顺序查找
app.use(express.static('静态文件夹'))
// 挂载路径前缀
app.use('/public',express.static('静态文件夹'))
(7)nodemon安装
监听项目文件变动,自动重启项目
npm install -g nodemon
2、express路由
路由-映射关系
客户端请求与服务器处理函数之间的映射关系
三部分组成:请求的类型,请求的url地址,处理函数
app.METHOD(PATH,HANDLER)
路由的匹配过程,只有匹配的类型和url都正确,才会转到处理函数。顺序按照定义顺序进行匹配。
npm init
npm install express
// 创建index.js 入口文件
// 执行(或者nodemon index.js)
node index.js
// index.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(80, () => {
console.log('http://127.0.0.1');
});
3、路由模块化
为了方便对路由进行模块化的管理,Express 不建议将路由直接挂载到 app 上,而是推荐将路由抽离为单独的模块将路由抽离为单独模块的步骤如下:
① 创建路由模块对应的 js 文件
② 调用 express.Router() 函数创建路由对象
③ 向路由对象上挂载具体的路由
④ 使用 module.exports 向外共享路由对象
⑤ 使用 app.use() 函数注册路由模块
// user.js
const express = require('express');
var router = express.Router();
router.get('/user/list', (req, res) => {
res.send('Hello World!');
});
router.post('/user/add',(req,res)=>{
res.send('add new user')
})
module.exports = router;
// index.js
const express = require('express');
const userRouter = require('./router/user')
const app = express();
app.use(userRouter);
app.listen(80, () => {
console.log('http://127.0.0.1');
});
路由添加前缀
app.use('/api',userRouter);
4、常见的express中间件
中间件(Middleware),特指业务流程的中间处理环节。
注意:中间件函数的形参列表中,必须包含 next 参数。而路由处理函数中只包含req 和 res.
next函数的作用
实现多个中间件连续调用的关键,表示把流转关系转交给下一个中间件或路由。
const mw = function(req,res,next){
// 把流转关系转交下一个中间件或路由
next();
}
多个中间件之间,共享同一份 req 和 res。基于这样的特性,我们可以在上游的中间件中,统一为 req 或 res 对象添加自定义的属性或方法,供下游的中间件或路由进行使用。
注意:
- 一定在路由之前写中间件
- 客户端请求可以调用多个中间件
- 中间件要用next函数返回
- next()之后不要写别函数
- 调用多个中间件,共享req和res
(1) 全局生效的中间件(使用app.use调用)
可以在全局使用多个中间件调用
app.use( (req,res,next)=>{
// 第一个
next();
})
app.use( (req,res,next)=>{
// 第二个
next();
})
(2) 局部生效的中间件
app.get('/user',mw,(req,res)=>{
res.send("hello word")
})
//多个的情况
app.get('/user',mw1,mw2,(req,res)=>{
res.send("hello word")
})
app.get('/user',[mw1,mw2],(req,res)=>{
res.send("hello word")
})
中间件的分类
- 应用级别中间键(通过use(),get(),post()挂载到app实例上)
- 路由级别中间件(绑定到express.Router上)
- 错误级别的中间件(捕获项目异常,参数顺序,err,req,res,next)
- express内置中间件(3个 :express.static;express.json;express.urlencoded)
- 第三方中间件
app.use(express.json);
app.use(express.urlencoded(({extended:false}))
自定义中间件步骤:
- 定义中间件
- 监听 req 的 data 事件
- 监听 req的 end 事件
- 使用 querystring 模块解析请求体数据
- 将解析出来的数据对象挂载为 req.body
- 封装到一个单独js模块
4、express创建API接口
创建一个基本服务器
const express = require('express');
const router = require('./apiRouter');
const app = express();
const port = process.env.PORT || 5000;
app.use('/',router);
app.listen(port,()=>{
console.log(`server running on port 127.0.0.1:${port}`)
})
get方法
const express = require('express');
const router = express.Router();
router.get('/user',(req,res)=>{
const query = req.query;
res.send({
status:0,
msg:'GET success!',
data:query
})
})
module.exports = router;
post方法
router.post('/add',(req,res)=>{
const body = req.body;
res.send({
status:0,
msg:'GET success!',
data:body
})
})
5、express跨域cors资源共享
解决接口跨域问题的方案主要有两种
- CORS(主流的解决方案,推荐使用)
- JSONP(有缺陷的解决方案:只支持 GET请求)
cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题使用步骤分为如下 3步:
- 运行 npm install cors 安装中间件
- 使用 const cors =require(cors”)导入中间件
- 在路由之前调用 app.use(cors())配置中间件
CORS(Cross-Origin Resource Sharing,跨域资源共享)由一系列 HTTP 响应头组成,这些 HTTP 响应头决定浏览器是否阻止前端 JS 代码跨域获取资源。
浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头就可以解除浏览器端的跨域访问限制。
- CORS 主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了 CORS 的接口。
- CORS 在浏览器中有兼容性。只有支持 XMLHttpRequest Level2 的浏览器,才能正常访问开启了 CORS 的服务端接口(例如:IE10+、Chrome4+、FireFox3.5+)
响应头
Access-Control-Allow-Origin:响应头部中可以携带一个 Access-Control-Allow-Origin 字段,
Access-Control-Allow-Headers:默认情况下,CORS 仅支持客户端向服务器发送如下的9个请求头: Accept,Accept-Language、Content-Language、DPR、Downlink, Save-Data、 Viewport-Width、 Width.Content-Type(值仅限于 text/plain、multipart/form-data、application/x-www-form-urlencoded 三者之一)
如果客户端向服务器发送了额外的请求头信息,则需要在服务器端,通过 Access-Control-Allow-Headers 对额外的请求头进行声明,否则这次请求会失败!
Access-Control-Allow-Methods:默认情况下,CORS 仅支持客户端发起 GET、POST、HEAD 请求。如果果客户端希望通过 PUT、DELETE 等方式请求服务器的资源,则需要在服务器端,通过 Access-Control-Alow-Methods来指明实际请求所允许使用的 HTTP 方法。
预检请求
只要符合以下任何一个条件的请求,都需要进行预检请求:
- 请求方式为 GET、POST、HEAD 之外的请求 Method 类型
- 请求头中包含自定义头部字段
- 向服务器发送了 application/json 格式的数据
在浏览器与服务器正式通信之前,浏览器会先发送 OPTION 请求进行预检,以获知服务器是否允许该实际请求,所以这一次的 OPTION 请求称为“预检请求”服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。
简单请求的特点:客户端与服务器之间只会发生一次请求。
预检请求的特点:客户端与服务器之间会发生两次请求,OPTION 预检请求成功之后,才会发起真正的请求。
jsonp
实现 JSONP 接口的步骤
- 获取客户端发送过来的回调函数的名字
- 得到要通过 JSONP 形式发送给客户端的数据
- 根据前两步得到的数据,拼接出一个函数调用的字符串
- 把上一步拼接得到的字符串,响应给客户端的<script>标签进行解析执行