前端Nodejs-Day37
Express中间件的注意事项:
① 在路由之前注册中间件
② 客户端发送的请求可以调用多个中间件进行处理
③ 执行完中间件的业务代码,一定要调用next函数
④ 调用完next函数后,避免再继续编写代码。
⑤ 连续调用多个中间件,req和res对象是共享的。
中间件的分类:
1. 应用级别的中间件:即通过app.use或app.get或app.post绑定的中间件。
2. 路由级别的中间件:绑定到express.Router()实例上的中间件,用法与应用级别的中间件一致。
应用级别的中间件和路由级别中间件的差别:引用级别绑定到app实例上,路由级别绑定到router实例上。
3. 错误级别的中间件:专用捕获整个项目中发生异常错误的中间件。包含四个形参:err,req,res,next(需要放在所有路由之后,捕获所有错误!)
4. Express内置中间件:① express.static托管静态资源。② express.json解析JSON格式的请求体数据。③ express.urlencoded解析URL-encoded格式的请求体数据(JSON格式为对象格式,urlencoded为键值对格式,多个键值对间以&连接)
5. 第三方中间件:例如body-parser中间件用于解析post请求体的数据,和express.json、express.urlencoded类似。
使用Express编写接口:需要将路由模块化,给路由挂载具体的方法和请求。
使用Express编写GET接口:
// 挂载响应的路由
router.get('/get', (req, res) => {
// 获取到客户端发送的数据
const query = req.query
res.send({
status: 0, // 0代表接受成功 1代表失败
msg: '请求成功!', // 状态的描述
data: query //需要响应给客户端的数据
})
})
使用Express编写POST接口:
router.post('/post', (req, res) => {
// 获取客户端发送请求体,发送到服务器的数据
const body = req.body
res.send({
status: 0,
msg: 'POST请求成功!',
data: body
})
})
接口的跨域问题:cros和jsonp
CORS跨域资源共享:
- CORS(Cross-Origin Resource Sharing,跨域资源共享)解决跨域,是通过 HTTP 响应头决定浏览器是否阻止前端 JS 代码跨域获取资源
- 浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头,就可解除浏览器端的跨域访问限制
- CORS 主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了 CORS 的接口。
- CORS 在浏览器中有兼容性。只有支持 XMLHttpRequest Level2 的浏览器,才能正常访问开启了 CORS 的服务端接口(例如:IE10+、Chrome4+、FireFox3.5+)。
cros是第三方中间件,通过导入解决跨域问题
// 一定要在路由之前配置cors,解决跨域问题
const cors = require('cors')
// 注册cors
app.use(cors())
cors常见响应头:
- Access-Control-Allow-Origin:指定了允许访问该资源的外域URL
// 只允许来自百度的请求
res.setHeader('Access-Control-Allow-Origin', 'www.baidu.com')
// 允许来自任何域的请求
res.setHeader('Access-Control-Allow-Origin', '*')
- Access-Control-Allow-Headers:声明额外的请求头
// 允许客户端额外向服务器发送Content-Type和X-custom-Header请求头
res.setHeader('Access-Control-Allows-Headers', 'Content-Type', 'X-Custom-Header')
- Access-Control-Allow-Methods:声明允许客户端发起的请求类型(默认情况下只支持get、post、head请求)
// 只允许POST、GET、DELETE、HEAD请求方法
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, DELETE, HEAD')
// 允许所有的HTTP请求方法
res.setHeader('Access-Control-Allow-Methods', '*')
CORS请求分类:
简单请求:客户端与服务器只发生一次请求
- 请求方式:GET、POST、HEAD 三者之一
- HTTP 头部信息不超过以下几种字段:无自定义头部字段、Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、Width 、Content-Type(只有三个值 application/x-www-formurlencoded、multipart/form-data、text/plain)
预检请求:客户端与服务器发生两次请求,OPTION请求预检成功后,才会发起真正的请求
- 请求方式为 GET、POST、HEAD 之外的请求 Method 类型
- 请求头中包含自定义头部字段
- 向服务器发送了 application/json 格式的数据
在浏览器与服务器正式通信之前,浏览器会先发送 OPTION 请求进行预检,以获知服务器是否允许该实际请求,所以这一次的 OPTION 请求称为“预检请求”。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据
JSONP:浏览器通过script标签的src属性请求服务器上的数据,服务器返回函数的调用。这种请求方式就是JSONP
- JSON不属于真正的Ajax请求,因为没有使用XMLHttpRequest对象
- JSONP仅支持GET请求
// 必须在配置cors中间件之前配置JSONP接口
app.get('/api/jsonp', (req, res) => {
// 1.得到函数名称
const funcName = req.query.callback
// 2.调用发送到客户端的数据
const data = { name: 'lwh', age: 18 }
// 3.拼接出函数的调用
const scriptStr = `${funcName}(${JSON.stringify(data)})`
// 4.拼接后的字符串响应给客户端
res.send(scriptStr)
})
配置mysql模块:
1.安装mysql模块:npm install mysql
2.连接数据库:const db = mysql.createPool({})
// 导入mysql模块
const mysql = require('mysql')
// 建立连接
const db = mysql.createPool({
host: '127.0.0.1', // 数据库的 ip地址
user: 'root', // 数据库账号
password: 'nmsl4599', // 数据库密码
database: 'sys' // 要操作的数据库
})
3.测试是否正常工作:db.query()指定要执行的SQL语句,通过回调函数拿到执行结果
db.query('SELECT 1', (err, result) => {
if(err) return console.log(err.message);
console.log(result);
})