• 【学习Koa】原生koa2 静态资源服务器例子


    实现思路

    • 首先读取当前路径下所有的文件和文件夹
    • 当去点击某个列表项时判断其实文件还是文件夹,文件的话直接读取,文件夹则再次利用上一个步骤读取并展示

    文件结构

    文件结构

    代码

    index.js 入口文件

    const Koa = require('koa')
    const path = require('path')
    const getContent = require('./util/content')
    const mimes = require('./util/mimes')
    
    const app = new Koa()
    
    const staticPath = './static'
    
    function parseMime(url) {
      let extName = path.extname(url)
      extName = extName ? extName.slice(1) : 'unknown'
      return mimes[extName]
    }
    
    app.use(async (ctx) => {
    
      if (ctx.path === '/favicon.ico') return;
    
      let absoluteStaicPath = path.join(__dirname, staticPath)
      let content = await getContent(ctx, absoluteStaicPath)
      let mime = parseMime(ctx.url)
    
      if (mime) {
        ctx.type = mime
      }
    
      if (mime && (mime.includes('image/') || mime.includes('video/'))) {
        ctx.res.writeHead(200)
        ctx.res.write(content, 'binary')
        ctx.res.end()
      } else {
        ctx.body = content
      }
    
    })
    
    app.listen(3000, function (params) {
      console.log('running at 127.0.0.1:3000')
    })
    

    content.js 获取内容

    const fs = require('fs')
    const path = require('path')
    const dir = require('./dir')
    const file = require('./file')
    
    function getContent(ctx, absoluteStaticPath) {
      
      let reqPath = path.join(absoluteStaticPath, ctx.url)
      const exist = fs.existsSync(reqPath)
      let content = ''
    
      if (!exist) {
        content = '404 not found'
      } else {
        let status = fs.statSync(reqPath)
    
        if (status.isDirectory()) {
          content = dir(ctx.path, reqPath)
        } else {
          content = file(reqPath)
        }
      }
    
      return content
    }
    
    module.exports = getContent
    

    file.js 读取文件

    const fs = require('fs')
    
    function file(reqPath) {
      return fs.readFileSync(reqPath, 'binary')
    }
    
    module.exports = file
    

    dir.js 读取文件夹

    const walk = require('./walk')
    
    function dir(path, reqPath) {
    
      let {
        dirList,
        fileList
      } = walk(reqPath)
    
      let html = ''
      function category(path, type, list) {
        html += `<h2>${type}: </h2>`
        html += '<ul>'
        for (const item of list) {
          html += `<li><a href="${path === '/' ? '' : path}/${item}">${item}</a></li>`
        }
        html += '</ul>'
      }
      
      dirList.length && category(path, '文件夹', dirList)
      fileList.length && category(path, '文件', fileList)
    
      return html
    }
    
    module.exports = dir
    

    walk.js 遍历目录,归类文件和文件夹

    const fs = require('fs')
    const mimes = require('./mimes')
    
    function walk(reqPath) {
    
      const dirList = [], fileList = []
      const files =  fs.readdirSync(reqPath)
    
      for (const file of files) {
        // 判断文件是文件夹还是文件
        let file_split = file.split('.')
        // 根据mime类型判断, 因为文件夹的名字也中也是可以带有.的
        let mimeType = file_split.length > 1 ? file_split[file_split.length-1] : ''
    
        if (mimes[mimeType] === void 0) {
          dirList.push(file)
        } else {
          fileList.push(file)
        }
      }
      
      return { dirList, fileList }
    }
    
    module.exports = walk
    

    mimes.js

    const mimes = {
      'css': 'text/css',
      'less': 'text/css',
      'txt': 'text/plain',
      'html': 'text/html',
      'xml': 'text/xml',
      'js': 'text/javascript',
      'json': 'application/json',
      'pdf': 'application/pdf',
      'wav': 'audio/x-wav',
      'wmv': 'video/x-mx-wmv',
      'gif': 'image/gif',
      'jpeg': 'image/jpeg',
      'jpg': 'image/jpeg',
      'png': 'image/png',
      'svg': 'image/svg+xml',
      'tiff': 'image/tiff',
      'icon': 'image/x-icon',
      'mp4': 'video/mp4'
    }
    
    module.exports = mimes
    

    结果


    来源

    原生koa2 静态资源服务器例子

  • 相关阅读:
    PHP $_GET 获取 HTML表单(Form) 或url数据
    dedecms {dede:php}标签用法介绍
    php 连接mysql实例代码
    php 常量、变量用法详细介绍
    mysql出现too many connections错误提示
    支持中文字母数字、自定义字体php验证码程序
    我的LinqToSql学习笔记(1)
    使用Git新建项目 (命令行)
    使用SQL Server Profiler
    sqlserver2008 中使用 表值 参数
  • 原文地址:https://www.cnblogs.com/guanine/p/9348184.html
Copyright © 2020-2023  润新知