前言
狭义中间件 请求/拦截,最典型的场景是 Koa.js 传输静态文件中间件的实现koa-send
。Koa.js 官方对 koa-send
进行二次封装,推出了koa-static
中间件,目标是用于做静态服务器或者项目静态资源管理。
本节主要以官方的
koa-static
中间件为参考,基于上一节实现的最简单koa-send
, 实现了一个最简单的koa-static
中间件,方便原理讲解和后续二次自定义优化开发。
实现步骤
- step 01 配置静态资源绝对目录地址
- step 02 判断是否支持等待其他请求
- step 03 判断是否为 GET 和 HEAD 类型的请求
step 04 通过
koa-send
中间件读取和返回静态文件实现源码
demo源码
https://github.com/chenshenhai/koajs-design-note/tree/master/demo/chapter-04-03## 安装依赖
npm i
## 执行 demo
npm run start
## 最后启动chrome浏览器访问
## http://127.0.0.1:3000/index.html
koa-static 依赖
koa-send
中间件,这里只用了上一节实现的最简单koa-send
koa-static 解读
const {resolve} = require('path');
const send = require('./send');
function statics(opts = {
root: ''
}) {
opts.root = resolve(opts.root);
// 是否需要等待其他请求
if (opts.defer !== true) {
// 如果需要等待其他请求
return async function statics(ctx, next) {
let done = false;
if (ctx.method === 'HEAD' || ctx.method === 'GET') {
try {
await send(ctx, ctx.path, opts);
done = true;
} catch (err) {
if (err.status !== 404) {
throw err;
}
}
}
if (!done) {
await next();
}
};
} else {
// 如果不需要等待其他请求
return async function statics(ctx, next) {
await next();
if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {
return;
}
if (ctx.body != null || ctx.status !== 404) {
return;
}
try {
await send(ctx, ctx.path, opts);
} catch (err) {
if (err.status !== 404) {
throw err;
}
}
};
}
}
module.exports = statics;
koa-static 使用
const path = require('path');
const Koa = require('koa');
const statics = require('./index');
const app = new Koa();
const root = path.join(__dirname, './public');
app.use(statics({ root }));
app.use(async(ctx, next) => {
if (ctx.path === '/hello') {
ctx.body = 'hello world';
}
});
app.listen(3000);
console.log('listening on port 3000');
附录
参考