震惊,隔壁老王竟然用自己的闲置服务器做这件事???

前言

上周末去隔壁老王家做吃饭,发现他整个人显得奇奇怪怪,一个人在书房里偷偷的做某件事,为了一探究竟,趁老王家媳妇儿不注意,捉个现行!!!

原来他痛恨某网盘已久,知道今天需要下载自己曾经上传的一个不可描述的文件时,需要发现下载 6 个多小时,于是他忍无可忍,决定用自己高价购买的服务器搭建一款简易版的个人网盘,我软磨硬泡的求老王把源码拷贝给我了。

安装依赖项

这是一款基于 Node.js 使用 fsformidable 模块搭建个人网盘,fs 模块为 Node.js 内置模块,需要安装 formidable 模块

npm install formidable

在这里插入图片描述

服务

// 引用HTTP模块
const http = require("http");
// 引用fs模块
const fs = require('fs');
const url = require("url");
// 文件上传处理模块
const formidable = require('formidable');
// 创建服务
const server = http.createServer();
// 监听request事件
server.on("request", function(req, res) {
    if (pathname == '/' && req.method == 'GET') {
        fs.readFile("./index.html", "utf8", function(err, data) {
            res.end(data);
        })
    } else if (req.method == 'GET') {
        fs.readFile("." + pathname, function(err, data) {
            res.end(data);
        })
    }
});
// 开启服务 端口号3000
server.listen(3000)

后台接口

fs 读取文件夹

else if (pathname == '/dir' && req.method == 'GET') {
    fs.readdir("." + query.dir, (err, files) => {
        if (err) {
            console.log(err)
            var obj = {};
            obj.status = false;
            res.end(JSON.stringify(obj))
        } else {
            var obj = {};
            obj.status = true;
            obj.data = files;
            res.end(JSON.stringify(obj))
        }
    })
}

fs 判断是否为文件夹

else if (pathname == '/Selfile' && req.method == 'GET') {
    fs.stat("." + query.dirname, (err, stats) => {
        if (err) {
            var obj = {};
            obj.status = false;
            res.end(JSON.stringify(obj))
        } else {
            var obj = {};
            obj.status = true;
            obj.isDirectory = stats.isDirectory();
            res.end(JSON.stringify(obj));
        }
    })
}

fs 创建文件夹

else if (pathname == '/AddDir' && req.method == 'GET') {
    fs.mkdir("." + query.dirname, (err) => {
        if (err) {
            var obj = {};
            obj.status = false;
            res.end(JSON.stringify(obj))
        } else {
            var obj = {};
            obj.status = true;
            res.end(JSON.stringify(obj))
        }
    })
}

fs 删除文件夹

else if (pathname == '/DelDir' && req.method == 'GET') {
    fs.rmdir('.' + query.filename, function(err) {
        if (err) {
            var obj = {};
            obj.status = false;
            res.end(JSON.stringify(obj))
        } else {
            var obj = {};
            obj.status = true;
            res.end(JSON.stringify(obj))
        }
    })
}

fs 删除文件

else if (pathname == '/DelFile' && req.method == 'GET') {
    fs.unlink('.' + query.filename, function(err) {
        if (err) {
            var obj = {};
            obj.status = false;
            res.end(JSON.stringify(obj))
        } else {
            var obj = {};
            obj.status = true;
            res.end(JSON.stringify(obj))
        }
    })
}

上传文件

else if (pathname == '/Update' && req.method == 'POST') { // 上传文件
    // 处理上传的文件,保存到服务端指定位置
    var form = new formidable.IncomingForm();
    // 设置上传文件保存位置: 当前目录下的www文件夹
    form.uploadDir = './www';
    form.parse(req, function(err, fields, files) {
        if (err) {
            var obj = {};
            obj.status = false;
            res.end(JSON.stringify(obj))
        } else {
            // oldPath 保存的上传的名称
            var oldPath = files.filetoupload.path;
            console.log(oldPath)
                // newPath 保存的路径
            var newPath = form.uploadDir + '/' + files.filetoupload.name;

            // 将上传的名称更改为原来的名称
            fs.rename(oldPath, newPath, (err) => {
                if (err) {
                    var obj = {};
                    obj.status = false;
                    res.end(JSON.stringify(obj))
                } else {
                    var obj = {};
                    obj.status = true;
                    res.end(JSON.stringify(obj))
                }
            });
        }
    });
}

几个关键的 JS 逻辑

每做一次跳转,都需要保存每次文件夹的路径。

// 绑定双击事件
document.querySelectorAll('.oslist>div').forEach(ele => {
    ele.ondblclick = () => {
        // 如果当前为文件夹,双击点击进入文件夹。
        if (ele.getAttribute('type') == 'file') {
            // 设置请求的路径
            root = RootHistory.data[RootHistory.index];
            root += ('/' + ele.getAttribute('name'));
            // 当回退后进入新的文件夹,旧的路径被删除
            if (RootHistory.data.length > RootHistory.index + 1) {
                RootHistory.data.length = RootHistory.index + 1;
            }
            // 历史记录
            RootHistory.data.push(root);
            RootHistory.index = RootHistory.data.length - 1;
            // 获取目录
            GetDir((arr) => {
                view(arr);
            }, root)
        }
    }
});

删除文件夹时需要递归每一个文件夹

// 创建递归函数删除文件
function recursion(dir) {
    // dir为当前文件路径
    isDirectory(e => {
        // 如果是文件夹,判断文件夹是否为空
        if (e) {
            GetDir(e => {
                // 如果是非空文件夹,则递归
                if (e.length > 0) {
                    e.forEach(ele => {
                        return recursion(dir + "/" + ele);
                    })
                } else {
                    // console.log('删除文件' + dir)
                    // 删除空文件夹
                    deleteDir(e => {
                        if (e.status) {
                            let newdir = dir.split('/');
                            newdir.pop();
                            // 禁止删除WWW目录值更目录
                            if (newdir.length > 2) {
                                newdir = newdir.join('/');
                                return recursion(newdir);
                            }
                            document.getElementById('refresh').click();
                        } else {
                            console.log('删除失败');
                        }
                    }, dir)
                }
            }, dir)
        } else {
            // 删除文件
            deleteFile(e => {
                if (e.status) {
                    console.log('删除成功');
                    document.getElementById('refresh').click();
                } else {
                    console.log('删除失败')
                }
            }, dir)
        }
    }, dir)
}

上传文件需要使用 form 表单,使用 iframe 可以阻止页面跳转

<form action="Update" target="frame1" method="post" enctype="multipart/form-data" id="Update" style="display: none;">
    <input type="file" name="filetoupload" id="filebtn">
</form>
<iframe name="frame1" frameborder="0" height="40"></iframe>
// 请求上传文件
function updateFile() {
   var form = document.getElementById('Update');
   form.submit();
}

在学习完成源码以后,我果断把文件放在我的学生主机上,只需要把端口打开就可以访问了,我将源码也一并放在了隔壁老王写的网盘里,Rabbit Yun 源码 点击下载,欢迎大家下载。由于服务器是学生主机,下载速度可能会很慢,(绝对比某网盘要快!!!)请谅解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值