koa静态资源加载中间的实现

^_^的我 1年前 ⋅ 2309 阅读

原理

  • 检查指定目录下是否存在相应的请求资源,存在则读取,并发送到浏览器,不存在则执行下一个中间件
  1. nodejs 读取资源文件实现如下

    /**
     * 读取资源文件内容
     * @param {String} filepath 文件读取路径
     * @return Promise 反正文件流 
     */
    function getFileContent(filepath) {
        return new Promise((resolve, reject) => {
            // 创建文件读的流
            let stream = fs.createReadStream(filepath);
            if (!stream) {
                resolve('');
            }
            let responseData = [];
            // 保存读取的文件流
            stream.on("data", (chunk) => {
                responseData.push(chunk);
            });
            let finalData = null;
            // 读取结束合并所有流
            stream.on( 'end', () => {
                finalData = Buffer.concat( responseData );
                resolve(finalData);
            });
            stream.on("error", (err) => {
                reject(err);
            });
        });
    }
    
  2. 拦截所有的请求,过滤存在的静态资源

    /**
     * 读取资源文件内容
     * @param {String} staticBasePath 静态资源存放目录
     * @return Promise 返回中间件函数(koa中间件必须是函数)
     */
    function staticMiddleWare(staticBasePath) => {
        return async (ctx, next) => {
            // 获取请求的资源后缀,默认为文本文件
            let extname = path.extname(ctx.path) || ".txt";
            // 告诉浏览器资源类型
            ctx.type = staticType[extname];
            // 拼装完整的文件路径
            let loadFilePath = staticBasePath + "/" + ctx.path;
            // 检查文件是否存在
            let fileIsExists = fs.existsSync(loadFilePath);
            // 文件存在则获取文件状态
            let stat = fileIsExists ? fs.statSync(loadFilePath) : {};
            // 默认请求状态
            ctx.status = 200;
            if (!fileIsExists) {
                // 文件不存在时的处理(此处可以不处理,直接交个下个中间件处理,如果存在下一个中间件)
                ctx.status = 404;
                ctx.body = "404 not found";
            } else if (!stat.isFile()) {
                // 不是一个文件时交给下一个中间件处理,比如交给路由中间件处理
                return await next();
            } else {
                ctx.body = await getFileContent(loadFilePath);
            }
            await next();
        }
    }
    
  • 说明

    文中staticType的内容如下

      {
    	  ".*": "application/octet-stream",
        ".pdf": "application/pdf",
        ".ai": "application/postscript",
        ".xml": "text/xml"
      }
    

    如有问题请在下面留言


全部评论: 0

    我有话说: