Node.js + Express 实现简单的文件分享服务

效果图:

HTML源码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文件共享</title>
  <style>
    .title{
      text-align: center;
    }
    .table{
      width: 100%;
    }
    .thead{
      background-color: #ccc;
    }
    th{
      padding: 5px 0;
    }
    td{
      text-align: center;
      border-bottom: 1px dashed #999;
      padding: 3px 0;
    }
    .btn{
      color: #409eff;
      cursor: pointer;
    }
    .top{
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 5px 10px;
    }
    #list > tr:hover{
      background-color: #eee;
      
    }
  </style>
</head>
<body>
  <h1 class="title">欢迎使用文件共享</h1>
  <div class="top">
    <span id="nav">/</span>
    <div>
      <span class="btn" id="backUp">返回上一级</span>
      <span>共<span id="total">0</span>条</span>
    </div>
  </div>
  <table class="table">
    <thead class="thead">
      <tr>
        <th>文件名</th>
        <th>类型</th>
        <th>大小</th>
        <th>创建时间</th>
        <th>下载</th>
      </tr>
    </thead>
    <tbody id="list">
    </tbody>
  </table>
  <script>
    const listEl = document.querySelector('#list')
    const totalEl = document.querySelector('#total')
    const navEl = document.querySelector('#nav')
    const backUp = document.querySelector('#backUp')
    const nevList = []
    listEl.addEventListener('click',handleDownload)
    async function getList(query = ''){
       let result = ''
       if(query) {
        result = await fetch(`/list?pathName=${query}`)
        navEl.innerHTML = query
       }else{
        result = await fetch('/list')
        navEl.innerHTML = '/'
       }
       const {data} = await result.json()
       const elArr = []
       data.forEach(item => {
        elArr.push(`
        <tr>
          <td>${item.name}</td>
          <td>${item.type === 1 ?'文件' : '文件夹'}</td>
          <td>${item.size}</td>
          <td>${item.createTime}</td>
          <td class="btn"
          fileName="${item.name}"
          fileType="${item.type}"
          path="${item.path}">${item.type === 1  ? '下载' : '查看'}</td>
        </tr>
        `)
       })
       listEl.innerHTML = elArr.join('')
       totalEl.innerHTML = data.length
    }
    getList()
    function handleDownload(e){
      const fileName = e.target.attributes.filename.value
      const fileType = e.target.attributes.fileType.value
      const path = e.target.attributes.path.value
      if(!fileName) return
      if(fileType == 1) {
        window.open(path)
      }else{
        getList(path)
        nevList.push(path)
      }   
    }
    backUp.addEventListener('click',(e)=>{
      if(!nevList.length) return
      if(nevList.length < 2) {
        nevList.shift()
        getList('')
      }else{
        nevList.pop()
        getList(nevList[nevList.length - 1])
      }
    })
  </script>
</body>
</html>

Node 源码

const express = require('express')
const path = require('path')
const fs = require('fs')
const app = express()
// 常量
const pagePath = __dirname + '/index.html'
const staticPath = __dirname + '/static'
app.use(express.static('static'))
app.get('/', (req, res) => {
  res.sendFile(pagePath)
})

app.get('/list', (req, res) => {
  const { pathName } = req.query
  const filePath = pathName ? staticPath + `/${pathName}` : staticPath
  const result = []
  const allFiles = fs.readdirSync(filePath)
  allFiles.forEach(name => {
    const fileInfo = fs.statSync(`${filePath}/${name}`)
    result.push({
      name,
      path: pathName ? `${pathName}/${name}` : `/${name}`,
      size: computedSize(fileInfo.size),
      type: fileInfo.isFile() ? 1 : 0,
      createTime: fileInfo.ctime.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }),
    })
  })
  res.json({
    data: result,
  })
})

function computedSize(size) {
  const kb = size / 1024
  const mb = kb / 1024
  return mb.toFixed(2) + ' MB'
}
app.listen(9000, () => {
  console.log('server running port:9000')
})

目录层级:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值