【学习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 静态资源服务器例子

posted @ 2018-07-21 21:53  Guanine  阅读(2059)  评论(0编辑  收藏  举报