【Koa】 基于Node.js 的开发框架
1. 初始化项目 npm init -y
1.1 或者使用脚手架 npm install -g koa-generator 全局安装 【使用框架就无需执行其他命令 1/2/3.... 】
生成项目 koa2 <projectname> projectname即为项目名
这里可能需要再 package.json 中 改一下 dev 的 启动命令 反正我 windows不支持 得改一下
2. 安装 npm install koa
3. 使用 因为遵循的是Commonjs 而不是 vue 那样的 ES module 所以不能用 import 而是使用 require
const koa = require('koa');
const app = new koa()
app.use((ctx, next) => {
console.log('1-1')
next()
console.log('1-2')
})
app.use((ctx, next) => {
console.log('2-1')
next()
console.log('2-2')
})
app.use((ctx, next) => {
console.log('3-1')
next()
console.log('3-2')
})
打印结果
1-1 2-1 3-1 3-2 2-2 1-2
4. 中间件
app.use() 用于注册中间件
中间件是处理http请求和响应的函数
上下文对象 ctx(content) 包含了当前 http 请求相关的所有信息
// 添加中间件
app.use(async ctx => {
ctx.body = 'hellow, world'
})
5. 路由
安装
使用 npm i koa-router 兼容koa1 和 koa2 的历史版本
npm i @koa/router 专门为koa2设计的新版本
引入
const Router = require('koa-router'); 或者 const Router = require('@koa/router');
初始化实例 并且为所有路由添加统一前缀
// 添加路由统一前缀
const router = new Router({
prefix: '/api'
})
使用
app.use(router.routes()).use(router.allowedMethods())
如果客户端尝试对 /users 发送 DELETE 请求,由于我们没有定义 DELETE 方法的路由,allowedMethods() 会自动返回 405 状态码,并在 Allow 头中指出支持的方法(GET 和 POST)。
接口
GET请求
// query 传参
// http://localhost:3000/api/query?id=2&web=baidu.com
//
router.get('/query', async(ctx) => {
let id = ctx.query.id
let web = ctx.query.web
ctx.body = id + ':' + web
})
// params 传参
// http://localhost:3000/api/params/id/web/baidu.com
//
router.get('/params/:id/web/:web', async(ctx) => {
let id = ctx.params.id
let web = ctx.params.web
ctx.body = id + ':' + web
})
POST请求
使用POST请求需要安装 bodyparser 来解析body信息
安装 npm i @koa/bodyparser
使用
const BodyParser = require('koa-bodyparser'); //body解析中间件
const bodyparser = new BodyParser();
app.use(bodyparser)
接口
router.post('/submitInfo', async (ctx) => {
let params = ctx.request.body
if(params) {
data.push(params)
ctx.body = {
code: 200,
message: '提交成功'
}
} else {
ctx.body = {
code: 500,
message: '提交失败'
}
}
})
重定向
// 重定向路由
router.redirect('/test', 'https://www.baidu.com')
404 处理
// 在所有路由之后添加404处理函数
app.use(async ctx => {
if(!ctx.body) {
ctx.status = 404
ctx.body = '404 Not Found'
}
})
5. 错误处理
由于洋葱模型 会先执行后面next()里代码 出问题后还会回到catch中
// 错误处理中间件 app.use(async (ctx, next) => { try { await next() } catch (err) { ctx.status = 500 ctx.body = 'error' + err.message } })
更推荐使用中间件 koa--json-error
6. 跨域处理
需要使用 @koa/cors
使用
const cors = require('@koa/cors');
// koa请求跨域配置
app.use(
cors({
// 允许跨域请求的来源,返回请求头中的 origin 或空字符串
origin: (ctx) => {
return ctx.request.headers.origin || "";
},
// 允许携带cookie
creadentials: true,
// 设置允许客户端获取的响应头
exposseHeaders: ["WWW-Authenticate", "Server-Authorization"],
// 设置允许的HTTP请求
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
// 设置允许的HTTP请求头
allowHeaders: ["Content-Type", "Authorization", "Accept"]
})
)
7. 上传图片
需要使用 @koa/multer
使用 ※ 需要现在对应位置创建上传文件夹
const Multer = require('@koa/multer')
const path = require('path')
// 配置磁盘存储引擎
const storage = Multer.diskStorage({
// 指定文件保存路径
destination: (req, file, cb) => {
// 当前文件夹下的uploads文件夹
cb(null, './uploads')
},
// 设置文件名
filename: (req, file, cb) => {
cb(null, Date.now() + path.extname(file.originalname))
}
})
// 实例化multer
const multer = Multer({
storage
})
接口
router.post('/upload', multer.single('file'), async ctx => {
// 获取上传的文件信息
const file = ctx.request.file
if(file) {
console.log(file)
ctx.body = '上传成功'
}
})
8. Cookie
在服务器端返回时并设置cookie
// cookie router.get('/cookie', async (ctx) => { // 基本设置cookie 中文需要转码 ctx.cookies.set('name', encodeURIComponent('张三')); // 设置cookie 并配置配置项 ctx.cookies.set("web", "www.baidu.com", { // cookie有效时长 maxAge: 1000 * 60 * 60 * 24 * 7, // cookie失效时间 expires: new Date('2019-08-12'), // 是否只用于http请求中获取 httpOnly: false, // 是否允许重写 overwrite: false, }) ctx.body = 'cookie设置成功' })
9. Session
10. JWT (Json Web Token)
JWT 由三部分组成 Header (头部) Payload (负载) Signatrue (签名)
是一种基于令牌(Token)的认证和授权机制
使用需安装插件 jsonwebtoken
npm i jsonwebtoken
使用
const JTW = require('jsonwebtoken')
编写 生成 token 和解析token 的方法
// 生成token let generateToken = (key) => { // 用户唯一id let id = 1 // 当前时间戳 单位秒 let now = Math.floor(Date.now() / 1000) let expire = 24 * 60 * 60 // 负载 let payload = { // Subject 主题(用户唯一id) sub: id, // 发行者 iss: 'benfeng', // 发行时间 iat: now, // 生效时间 nbf: now, // 过期时间 exp: now + expire, // aud: [''], // 自定义数据 data: { name: '贲风', gender: '男' } } // 使用负载、秘钥和指定的签名算法(HS256)生成token let token = JTW.sign(payload, key, { algorithm: 'HS256' }) return token }
// 解析token let parseToken = (token, key) => { let payload = JTW.verify(token, key, { algorithm: 'HS256' }) console.log('解析的payload', payload) }
请求时传key 就可以换取token
// JWT接口 router.get('/token', async ctx => { let key = 'koaTest' let token = generateToken(key) ctx.body = token })
11.连接数据库( mongoDB)
安装插件 mongoose
npm i mongoose --save
先单独创建一个js 文件
const mongoose = require('mongoose');
module.exports = () => {
// mongodb数据库地址
mongoose.connect('mongodb://localhost:27017/backgroundDatas', {
}).then(() => {
console.log('数据库连接成功');
}).catch(err => {
console.log('数据库连接失败', err);
})
}
在app.js 即入口文件中引入并使用
const MongoConnect = require('./db')
// 连接数据库
MongoConnect()
设计用户模块的schema 【这里我对后端的具体说法不太懂 学习中...】
const mongoose = require('mongoose');
// 数据表名称
// const schema = new mongoose.Schema({
// // 定义字段 以及字段类型
// p1: String,
// p2: String
// })
// 创建模型对象
// const obj = mongoose.model('obj', schema)
const userSchema = new mongoose.Schema({
username: String,
password: String
})
const User = mongoose.model('User', userSchema)
module.exports = {
User
}
mongodb 操作数据库增删改查 【应该不全 目前只记录我用了的】
// 引入模型对象 const { User } = require('../models/index') // 增 create User.create({ username, password }) // 删 findOneAndDelete User.findOneAndDelete({ id }) // 改 updateOne // 两个参数 第一个是识别标志 第二个是要覆盖哪些参数 User.updateOne( { _id: params._id }, { username: params.username, password: params.password } ) // 查 // 查单个 findOne // 查所有 find User.findOne({ _id: ctx.params.id })
12. 监听端口 示例为 3000 端口 成功启动就会执行回调函数
const hostname = '127.0.0.1';
const port = 3000;
// 监听端口
app.listen(port, hostname, () => {
console.log(`服务器启动成功: http://${hostname}:${port}`)
});
浙公网安备 33010602011771号