当前位置:网站首页 > 更多 > 站长帮 > 正文

[建站测试] 校园网内简易p2p文件分享平台的手动实现

作者:CC下载站 日期:2021-10-12 04:41:02 浏览:6 分类:站长帮

背景

开学一个多月了,由于繁重的学业和懒惰,都没怎么更新有意思的博客。

前几天突然想到了一个想法。同学之间平常用网络分享一个文件,大部分都是用的qq。但是qq看起来把文件拖到聊天框点击发送就发给对面同学了。但是实际上是先上传到了腾讯的服务器,然后对面的同学再从服务器上下载。

这一上传一下载就很耽误时间。我就想在我的电脑上开一个文件上传服务,别的同学直接上传到我的机械革命上,上传完毕,我就得到了这个文件,不用再下载一遍。而且由于是校园网内的服务,速度也有保障。

语言选择

由于前几天做了几道python flask模板注入的题目,便打算拿flask来当后端练练手,提供http服务。

前端的话还是利用漂亮且方便易用的fomantic-ui解决html和css样式问题,再配合上大大简化js编程的Jquery来写效果和功能。

遇到的困难

单纯的文件上传十分简单。对付小文件还好,但是大文件就会出现页面停滞的情况,而用户收不到任何反馈,不知道到底是在上传还是崩溃了。我们需要设置一个上传进度条来给以用户友善的提示。所以这里就有一个问题,如何获得上传的进度?

查询资料过后,我发现XMLHttpRequest能够获取进度。然后我又发现Jquery中封装的$.ajax能够更加简单的实现。参考链接 https://stackoverflow.com/questions/13203231/is-there-any-way-to-get-jquery-ajax-upload-progress

代码

[建站测试] 校园网内简易p2p文件分享平台的手动实现


<!DOCTYPE html>
<html>
<head>
 <meta charset="utf8" />
 <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
 <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.css" />
 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.js"></script>
 <title>wuuconix&#x27;s page</title>
</head>
<body>
   <div style="padding-top: 5em;"></div>
   <div class="ui text container">
       <div class="ui placeholder segment">
           {% if filelist == [] %}
               <div class="ui icon header">
                   <i class="pdf file outline icon"></i>
                   目前文件夹里空空如也
               </div>
           {% else %}
               <div class="ui list">
               {% for file in filelist%}
                   <div class="item">
                       <i class="file icon"></i>
                       <div class="content">
                           <a class="header" href="download/{{file}}" data-content="点击下载{{file}}" id="files">{{file}}</a>
                       </div>
                   </div>
               {% endfor %}
               </div>
           {% endif %}
           <div class="ui buttons">
               <button class="ui primary button" id="button_choose">选择文件</button>
               <button class="ui positive button" id="button_submit">上传</button>
           </div>
           <form action="/upload" method="post" enctype="multipart/form-data" id="form">
               <input type="file" id="input_file" style="display: none;" name="file">
           </form>
           <div class="ui divider"></div>
           <div class="ui indicating progress" id="progress" data-value="0" data-total="100">
               <div class="bar">
                   <div class="progress"></div>
               </div>
               <div class="label"></div>
           </div>
       </div>
   </div>
</body>

<script>
   $(document).ready(function(){
       $("#progress").hide();
       $("#button_submit").attr("disabled", true);
   });
   $("#button_choose").click(function()
   {
       $("#input_file").click();
   });
   $("#input_file").bind("input propertychange",function(){
       var name = ($(this).prop(&#x27;files&#x27;)[0][&#x27;name&#x27;]);
       $("#button_submit").attr("disabled", false);
       $(&#x27;#button_choose&#x27;)[0].innerHTML=name;
   });
   $("#button_submit").click(function()
   {
       $("#progress").show();
       var formdata = new FormData($("#form")[0]);
       $.ajax({
           url:&#x27;/upload&#x27;,
           type:&#x27;post&#x27;,
           xhr: function () {
               var xhr = $.ajaxSettings.xhr();
               var starttime = Math.ceil(new Date().getTime() / 1000);
               xhr.upload.onprogress = function (e) {
                   if (e.lengthComputable) {
                       var uploaded = Math.ceil(e.loaded / Math.pow(1024,2));
                       var spenttime = Math.ceil(new Date().getTime() / 1000) - starttime;
                       var speed = (uploaded / spenttime).toFixed(2);
                       var progress = Math.ceil(e.loaded / e.total * 100);
                       $("#progress").attr(&#x27;data-value&#x27;, progress);
                       $("#progress").progress(&#x27;update progress&#x27;, progress);
                       $("#progress").progress(&#x27;set label&#x27;, speed + "MB/s");
                   }
               };
               return xhr;
           },
           processData:false,
           contentType:false,
           data:formdata,
           success:function (data) {
               $(&#x27;body&#x27;).toast({
                   title: &#x27;恭喜你&#x27;,
                   message: "你已经成功将 《" + $(&#x27;#button_choose&#x27;)[0].innerHTML + "》 上传至了武丑兄的机械革命。页面即将自动刷新",
                   showProgress: &#x27;bottom&#x27;,
                   classProgress: &#x27;red&#x27;
               });
               setTimeout("location.reload();", 3000)  
           }
       })
   });
   $(&#x27;#progress&#x27;).progress({
       label: &#x27;percent&#x27;,
   });
   $(&#x27;a&#x27;).popup({
       on: &#x27;hover&#x27;


from flask import render_template, Flask, request, make_response, send_from_directory
import os

def get_filelist():
   filelist = os.listdir("upload/")
   return filelist

app = Flask(__name__)

@app.route(&#x27;/&#x27;)
def hello(filelist=[]):
   return render_template("index.html", filelist=get_filelist())

@app.route(&#x27;/upload&#x27;,methods=[&#x27;GET&#x27;,&#x27;POST&#x27;])
def upload():
   if request.method == &#x27;POST&#x27;:
       f = request.files[&#x27;file&#x27;]
       print(request.files)
       f.save(f"upload/{f.filename}")
       filelist = get_filelist()
       return render_template("index.html", filelist=filelist)
   else:
       return render_template("index.html", filelist=get_filelist())

@app.route(&#x27;/download/<filename>&#x27;,methods=[&#x27;GET&#x27;])
def download(filename):
   response = make_response(send_from_directory("upload", filename, as_attachment=True))
   response.headers["Content-Disposition"] = "attachment; filename={}".format(filename.encode().decode(&#x27;latin-1&#x27;))
   return response
   
if __name__ == &#x27;__main__&#x27;:
   app.run(host=&#x27;0.0.0.0&#x27;, port=80)

效果

[建站测试] 校园网内简易p2p文件分享平台的手动实现

[建站测试] 校园网内简易p2p文件分享平台的手动实现

[建站测试] 校园网内简易p2p文件分享平台的手动实现

[建站测试] 校园网内简易p2p文件分享平台的手动实现

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯