1. Introducción
Koa fue creado por el equipo original de Express y está comprometido a convertirse en un marco web más pequeño, más expresivo y más sólido. El uso de koa para escribir aplicaciones web, mediante la combinación de diferentes generadores, puede evitar el anidamiento repetido y tedioso de las funciones de devolución de llamada y mejorar en gran medida la eficiencia del manejo de errores. Koa no vincula ningún middleware en el método kernel, solo proporciona una biblioteca de funciones liviana y elegante, lo que hace que escribir aplicaciones web sea práctico.
2. Inicio rápido
2.1 Instalar koa2
# 初始化package.json
npm init
# 安装koa2
npm install koa
2.2 código hola mundo
const Koa = require('koa')
const app = new Koa()
app.use( async ( ctx ) => {
ctx.body = 'hello koa2' //json数据
})
app.listen(3000)
2.3 inicio
node index.js
3. koa contra expreso
Suele decirse que Koa es un modelo cebolla, que se centra en el diseño de middleware. Pero de acuerdo con el análisis anterior, encontrará que Express es similar, la diferencia es que el mecanismo de middleware Express utiliza la implementación de devolución de llamada, por lo que si hay asincronía, puede confundirlo en el orden de ejecución, por lo que si queremos hacer interfaz Estadísticas que consumen mucho tiempo, el manejo de errores El patrón de middleware de Koa es más conveniente de manejar. El último punto del mecanismo de respuesta también es muy importante, Koa no responde de inmediato, sino que responde en la capa más externa después de que se completa todo el procesamiento del middleware, mientras que Express responde de inmediato.
3.1 más ligero
- koa no proporciona middleware incorporado;
- Koa no proporciona enrutamiento, pero separa la biblioteca de enrutamiento (koa/router)
3.2 Objeto de contexto
Koa agrega un objeto de contexto como el objeto de contexto de esta solicitud (pasado como el primer parámetro del middleware en koa2). Al mismo tiempo, dos objetos, Solicitud y Respuesta, también se montan en el Contexto. Al igual que Express, ambos objetos proporcionan una gran cantidad de métodos convenientes para ayudar al desarrollo, por lo que es más razonable guardar algunos parámetros públicos.
3.3 Control de procesos asíncrono
express
Adoptar callback
para manejar async, koa v1
adopt generator
, koa v2
adopt async/await
. generator
Y async/await
use la escritura síncrona para lidiar con la asíncrona, que obviamente es mejor que callback
y promise
.
3.4 Modelo de software intermedio
express
Basado en connect
middleware, modelo lineal; koa
Middleware adopta el modelo de cebolla (para cada middleware, después de completar algunas cosas, puede pasar el control de manera muy elegante al siguiente middleware y puede esperar a que se complete, cuando el subsiguiente Después de que el middleware termine de procesarse, el control vuelve a sí mismo)
//同步
var express = require("express")
var app = express()
app.use((req,res,next)=>{
console.log(1)
next()
console.log(4)
res.send("hello")
})
app.use(()=>{
console.log(3)
})
app.listen(3000)
//异步
var express = require("express")
var app = express()
app.use(async (req,res,next)=>{
console.log(1)
await next()
console.log(4)
res.send("hello")
})
app.use(async ()=>{
console.log(2)
await delay(1)
console.log(3)
})
function delay(time){
return new Promise((resolve,reject)=>{
setTimeout(resolve,1000)
})
}
//同步
var koa = require("koa")
var app = new koa()
app.use((ctx,next)=>{
console.log(1)
next()
console.log(4)
ctx.body="hello"
})
app.use(()=>{
console.log(3)
})
app.listen(3000)
//异步
var koa = require("koa")
var app = new koa()
app.use(async (ctx,next)=>{
console.log(1)
await next()
console.log(4)
ctx.body="hello"
})
app.use(async ()=>{
console.log(2)
await delay(1)
console.log(3)
})
function delay(time){
return new Promise((resolve,reject)=>{
setTimeout(resolve,1000)
})
}
app.listen(3000)
4. Enrutamiento
4.1 Uso básico
var Koa = require("koa")
var Router = require("koa-router")
var app = new Koa()
var router = new Router()
router.post("/list",(ctx)=>{
ctx.body=["111","222","333"]
})
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)
4.2 rol router.allowedMethods
4.3 Método de solicitud
Métodos de solicitud del enrutador Koa: get , put , post , patch , delete , del , y el método de uso es enrutador.método(), como enrutador.get() y enrutador.post(). Y router.all() coincidirá con todos los métodos de solicitud.
var Koa = require("koa")
var Router = require("koa-router")
var app = new Koa()
var router = new Router()
router.get("/user",(ctx)=>{
ctx.body=["aaa","bbb","ccc"]
})
.put("/user/:id",(ctx)=>{
ctx.body={
ok:1,info:"user update"}
})
.post("/user",(ctx)=>{
ctx.body={
ok:1,info:"user post"}
})
.del("/user/:id",(ctx)=>{
ctx.body={
ok:1,info:"user del"}
})
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)
4.4 Enrutamiento dividido
routes/list.js
var Router = require("koa-router")
var router = new Router()
router.get("/",(ctx)=>{
ctx.body=["111","222","333"]
})
.put("/:id",(ctx)=>{
ctx.body={
ok:1,info:"list update"}
})
.post("/",(ctx)=>{
ctx.body={
ok:1,info:"list post"}
})
.del("/:id",(ctx)=>{
ctx.body={
ok:1,info:"list del"}
})
module.exports = router
routes/index.js
var Router = require("koa-router")
var user = require("./user")
var list = require("./list")
var router = new Router()
router.use('/user', user.routes(), user.allowedMethods())
router.use('/list', list.routes(), list.allowedMethods())
module.exports = router
entry入口
var Koa = require("koa")
var router = require("./routes")
var app = new Koa()
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)
4.5 Prefijo de enrutamiento
router.prefix('/api')
router.use('/user', user.routes(), user.allowedMethods())
4.6 Redirección de enrutamiento
router.get("/home",(ctx)=>{
ctx.body="home页面"
})
//写法1
router.redirect('/', '/home'); //匹配到/重定向到/home
//写法2
router.get("/",(ctx, next)=>{
ctx.redirect("/home")
})
5. Recursos estáticos
const Koa = require('koa')
const path = require('path')
const static = require('koa-static')
const app = new Koa()
app.use(static(path.join( __dirname, "public")))
app.use( async ( ctx ) => {
ctx.body = 'hello world'
})
app.listen(3000)
6. Obtener parámetros de solicitud
6.1 Obtener parámetros
En koa, la fuente de datos para la solicitud GET es el método de consulta o el método de cadena de consulta en el objeto de solicitud en koa.
query devuelve un objeto de parámetro formateado, y querystring devuelve una cadena de solicitud Dado que ctx se refiere directamente a la API de solicitud, hay dos formas de obtener datos de solicitud GET.
- Obtenga el objeto de solicitud ctx.query directamente del contexto, devuelva como { a: 1, b: 2 } cadena de solicitud ctx.querystring, devuelva como a = 1 & b = 2
- Obtenga el objeto de solicitud ctx.request.query del objeto de solicitud del contexto, devuelva como { a:1, b:2 } cadena de solicitud ctx.request.querystring, devuelva como a=1&b=2
6.2 parámetros de publicación
Para el procesamiento de solicitudes POST, el middleware koa-bodyparser puede analizar los datos formData del contexto koa2 en ctx.request.body
const bodyParser = require('koa-bodyparser')
// 使用ctx.body解析中间件
app.use(bodyParser())
7. plantilla ejs
7.1 Instalación de módulos
# 安装koa模板使用中间件
npm install --save koa-views
# 安装ejs模板引擎
npm install --save ejs
7.2 Uso de motores de plantillas
Directorio de archivos
├── package.json
├── index.js
└── view
└── index.ejs
Archivo ./index.js
const Koa = require('koa')
const views = require('koa-views')
const path = require('path')
const app = new Koa()
// 加载模板引擎
app.use(views(path.join(__dirname, './view'), {
extension: 'ejs'
}))
app.use( async ( ctx ) => {
let title = 'hello koa2'
await ctx.render('index', {
title: 'hello world',
})
})
app.listen(3000)
Plantilla ./view/index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
<p>EJS Welcome to <%= title %></p>
</body>
</html>
8. cookie y sesión
8.1 galleta
Koa proporciona métodos para leer y escribir cookies directamente desde el contexto
- ctx.cookies.get(nombre, [opciones]) lee la cookie en la solicitud de contexto
- ctx.cookies.set(nombre, valor, [opciones]) escribir cookie en contexto
8.2 sesión
- koa-session-minimal es un middleware de sesión para koa2, que proporciona una interfaz de lectura y escritura para medios de almacenamiento.
const session = require('koa-session-minimal')
app.use(session({
key: 'SESSION_ID',
cookie: {
maxAge:1000*60
}
}))
app.use(async (ctx, next) => {
//排除login相关的路由和接口
if (ctx.url.includes("login")) {
await next()
return
}
if (ctx.session.user) {
//重新设置sesssion
ctx.session.mydate = Date.now()
await next()
} else {
ctx.redirect("/login")
}
})
9. Sube fotos
9.1 Medio ambiente
- koa: utilizado para iniciar un servidor web
- koa2-cors: resuelve problemas entre dominios
- koa-router: procesamiento de enrutamiento koa
- koa-body: adquisición de parámetros de koa
- koa-static: configuración de recursos estáticos
- @koa/multer and multer: plugin para subir imágenes
9.2 Estructura del código
9.3 Implementación
- Paso 1: Cree un servicio web simple con koa+koa-router
//main.js
const Koa = require('koa') // 引入koa
const Router = require('koa-router') // 引入koa-router
const {
koaBody } = require('koa-body');
var router = new Router()
router.get('/', async (ctx) => {
ctx.type = 'html'
ctx.body = '<h1>hello world!</h1>'
}).post('/upload', async (ctx) => {
ctx.body = 'ok'
})
app.use(koaBody())
.use(router.routes())
.use(router.allowedMethods())
app.listen(3000)
Ahora podemos abrir http://localhost:3000 para ver hola mundo
- Luego creamos una nueva carpeta de carga y agregamos el código de contenido estático al código
//mian.js 新增代码
const static = require('koa-static')
const path = require('path')
app.use(router.routes())
.use(router.allowedMethods())
.use(static(path.join(__dirname, './upload')))
En este punto, si agrega una nueva foto en la carpeta de carga, puede http://localhost:3000/***.png
verla a través de . (***: Agrega un sufijo al nombre de la foto que agregaste tú mismo)
- En este punto, agregue un archivo index.html y agregue el siguiente código
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="file" class="file" name="avatar">
<button onclick="send()">上传</button>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
let formData = new FormData()
document.querySelector('.file').addEventListener('change', function(e) {
let files = e.target.files
console.log(files)
if (!files.length) return
formData.append('file', files[0], files[0].name)
})
function send(){
axios.post('http://localhost:3000/upload',formData,{
Headers:{
"Content-type":"multipart/form-data"
}
})
}
</script>
</body>
</html>
Si selecciona una imagen y la carga, encontrará que hay un problema entre dominios, luego, si encuentra el problema y lo resuelve, cargue directamente el código:
//mian.js新增代码
const cors = require('koa2-cors')
//注意这个配置要在router前使用不然不生效
app.use(cors())
.use(koaBody())
.use(router.routes())
.use(router.allowedMethods())
.use(static(path.join(__dirname, './upload')) )
Después de resolver el dominio cruzado, seleccione la imagen y cárguela. En este momento, tenemos los datos pasados y se acerca el evento principal: @koa/multer uses
const multer = require('@koa/multer')
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './upload')
},
filename: function (req, file, cb) {
const fileFormat = (file.originalname).split('.')
cb(null, Date.now() + '.' + fileFormat[fileFormat.length - 1])
}
})
const upload = multer({
storage })
Modificar/cargar después de la configuración
router.post('/upload', upload.single('file'), async (ctx) => {
console.log('ctx.file', ctx.file)
})
Nota: Debe tenerse en cuenta que el archivo en upload.single('file') debe ser consistente con el campo formData en el index.html anterior. En este momento, puede cargar felizmente ~~~
10. Registro
const Koa = require('koa')
const Router = require('koa-router')
// 引入 koa-logger
const logger = require('koa-logger')
const app = new Koa()
const router = new Router()
// 使用 koa-logger 中间件
app.use(logger((str, args) => {
// console.log(str);
// console.log(args);
}))
router.get('/', ctx => {
ctx.body = '首页'
})
// 使用路由中间件
app.use(router.routes())
app.listen(3000, () => {
console.log('listen 3000 ok');
})
- Se puede pasar una función al registrar el middleware koa-logger, que tiene 2 parámetros
- str es un tipo de cadena. Cuando se produce una solicitud, str contiene información sobre el tipo de solicitud y la ruta de la solicitud. Cuando se produce una respuesta, str contiene información sobre el código de estado de la respuesta, la duración de la respuesta y el tamaño del archivo de respuesta.
- args es un tipo de matriz. Cuando se produce una solicitud, el tipo de solicitud y la ruta de la solicitud se colocarán en la matriz. Cuando se produzca una respuesta, el código de estado de la respuesta, la duración de la respuesta y la información del tamaño del archivo de respuesta se colocarán en la matriz.