实现思路
- 首先读取当前路径下所有的文件和文件夹
- 当去点击某个列表项时判断其实文件还是文件夹,文件的话直接读取,文件夹则再次利用上一个步骤读取并展示
文件结构
代码
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
结果