node---express
主要记录express的基本使用,系统学习可以去官网
express中文网
初探express
什么是express
express是基于node的一个服务器框架,它是对http模块的封装,简化了node服务器的创建。
目前已经有不错的生态,但他的作者又制作了koa2,我觉得这个东西估计用不久,简单看看就好了。
基本使用
按照下面的指令来安装express框架
npm i express
可以按照下面的代码来创建一个最基本的服务器
const express = require('express');
const app = express();
app.listen(8080, () => {
console.log('服务器已经启动');
})
可以直接在服务器上挂载请求
// get请求
app.get('/user/:id',(req,res) => {
// req.qurey可以获取到用户发送的查询参数,默认情况下req.query是一个空的参数
// res.send(req.query)
// req.params可以获取到通过:匹配的动态参数
// 注意: 动态参数的名字会对应params的key名字 , 动态参数可以有多个
res.send(req.params)
})
可以使用static
方法来托管静态资源
对于use
函数之后再做解释
// 可以通过参数挂载路径前缀
// static传入静态资源文件夹的路径
app.use('/static' , express.static('public'))
nodemon
nodemon是一个node服务器的调试工具
可以让我们在修改代码之后不必再重启服务器
通过下面的指令来安装nodemon
npm i nodemon -g
通过nodemon来启动服务器
nodemon app.js
中间件
认识中间件
中间件就是服务器的一些处理程序,通过这些程序来连接前端数据和数据库
中间件本质就是一些函数,这些函数接收三个参数
- req:前端发送的数据
- res:用于向前端返回数据的对象
- next:交给下一个中间件
有点类似于vue的导航守卫,req和res是全局共享的,在执行next()之后,会将他们交给下一个中间件或者路由来处理。
例如:
// 这就是一个中间件函数
const mw = (req , res , next) => {
console.log('中间件处理完成');
next();
}
(路由就是一个特殊的中间件,只不过它没有next参数,作为处理的终点)
注意在next之后最后不要再出现任何代码,next要作为中间件的结尾
中间件的分类
全局中间件和局部中间件
- 通过 app.use() 注册的中间件称为全局中间件,这些中间件会在全局生效。
当注册多个中间件时会按照从上到下的顺序依次执行这些中间件。 - 在路由函数中注册的中间件称为局部中间件,也就是路由的处理函数。
官方分类
- 应用级别:通过app.use(),get(),post()等注册的中间件
- 路由级别:挂载在某个路由对象上的中间件
- 错误级别:这个中间件会在项目发生错误时被调用,它接收四个参数
err,req,res,next
,一般放在最后。 - 内置中间件:这些中间件不需要引入,可以直接使用
例如:-
static 托管静态资源
-
json 处理json数据
-
urlencoded 处理url-encoded格式的数据
-
- 第三方中间件:按照下载,引入,注册的顺序使用,具体有哪些好用的中间件之后再说。
路由
跟前端一样,路由就是映射关系,一个路由对应一个处理函数。
路由的组成
后端的路由由三部分组成:
- url
- 请求类型
- 处理函数
在前端发送请求时,只有url和请求类型都对应时才会执行对应的处理函数。
路由会按照从上到下的顺序依次匹配这些路由。
如果找到对应的路由久停止查找,或者直到最后也没有找到。
路由的使用
- 路由可以直接在app上进行挂载。
app.get('/user/:id',(req,res) => {
res.send('ok')
})
-
也可以使用模块化 的方式
- 创建路由
// 引入express框架 const express = require('express'); // 创建路由 const router = express.Router();
- 挂载请求
// 向路由挂载请求 router.get('/home',(req,res) => { res.send('<h1>这里是首页</h1>') }) router.get('/about',(req,res) => { res.send('<h1>这里是关于</h1>') })
- 导出路由对象
// 导出路由 module.exports = router;
- 注册路由
const router = require('./router.js') // app.use的作用就是注册全局中间件 // 在注册路由时也可以添加前缀 app.use(router);
接口
接口其实就是路由,不同的url对应不同的处理函数
接口编写
下面是一个接口示例,跟路由的写法几乎一样
const express = require('express')
const apiRouter = express.Router();
// 在这里编写接口
// get接口
apiRouter.get('/get',(req,res) => {
const query = req.query;
res.send({
status: 0,
msg: '请求成功',
data: query
})
})
跨域
只要协议、域名、ip、端口号
任意一项不同就会存在跨域问题
后端解决跨域问题有两种方案:cors和jsonp
cors
cors是express的一个第三方中间件
const cors = require('cors');
// 默认情况下,浏览器有同源安全策略
// 但是如果服务器配置了相关的响应头,就可以实现跨域请求
// cors就是由一系列的响应头组成的
app.use(cors())
原理
默认情况下,浏览器有同源安全策略
但是如果服务器配置了相关的响应头,就可以实现跨域请求
cors就是由一系列的响应头组成的
响应头
使用res.setHeader()来配置响应头
- Access-Control-Allow-Origin : 配置允许访问的外域url
- Access-Control-Allow-Headers:设置允许访问的请求头
- Access-Control-Allow-Methods:设置允许请求的请求类型
使用cors之后我们可以不用再去手动配置
简单请求和预检请求
cors的请求分为简单请求和预检请求。
默认的cors为简单请求
- 仅支持get、post、head请求
- http头部只支持默认的九种
简单请求的对立面就是预检请求
在发送这些请求的时候,浏览器会先尝试发送option告知服务器,当收到服务器允许访问的请求之后才会发送正式的请求
区别在于:
- 简单请求只会执行一次
- 预检请求会发送两次,一次发送option,一次发送正式请求
jsonp
jsonp不推荐使用,很麻烦,而且不属于ajax请求
通过script标签的src属性来向服务器发送请求,服务器返回一个函数并调用
但是这样仅支持get请求
并且不属于ajax
注意jsonp的接口需要在配置cors之前
服务器端返回的是一个立即执行函数
利用jquery配置dataType参数可以发送jsonp请求