【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()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 2 3 4 5 6 | 1-1 2-1 3-1 3-2 2-2 1-2 |
4. 中间件
app.use() 用于注册中间件
中间件是处理http请求和响应的函数
上下文对象 ctx(content) 包含了当前 http 请求相关的所有信息
1 2 3 4 | // 添加中间件 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');
初始化实例 并且为所有路由添加统一前缀
1 2 3 4 | // 添加路由统一前缀 const router = new Router({ prefix: '/api' }) |
使用
app.use(router.routes()).use(router.allowedMethods())
如果客户端尝试对 /users 发送 DELETE 请求,由于我们没有定义 DELETE 方法的路由,allowedMethods() 会自动返回 405 状态码,并在 Allow 头中指出支持的方法(GET 和 POST)。
接口
GET请求
1 2 3 4 5 6 7 8 | // 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 }) |
1 2 3 4 5 6 7 8 | // 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: '提交失败' } } })
重定向
1 2 | // 重定向路由 router.redirect( '/test' , 'https://www.baidu.com' ) |
404 处理
1 2 3 4 5 6 7 | // 在所有路由之后添加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 端口 成功启动就会执行回调函数
1 2 3 4 5 6 7 | const hostname = '127.0.0.1' ; const port = 3000; // 监听端口 app.listen(port, hostname, () => { console.log(`服务器启动成功: http: //${hostname}:${port}`) }); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix