koa-static 实现

前言

狭义中间件 请求/拦截,最典型的场景是 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');

附录

参考

results matching ""

    No results matching ""