开学一个多月了,由于繁重的学业和懒惰,都没怎么更新有意思的博客。
前几天突然想到了一个想法。同学之间平常用网络分享一个文件,大部分都是用的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
文件目录
- 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/fomantic-ui@2.8.8/dist/semantic.min.css" />
- <script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.js">script>
- <title>wuuconix's pagetitle>
- 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('files')[0]['name']);
- $("#button_submit").attr("disabled", false);
- $('#button_choose')[0].innerHTML=name;
- });
- $("#button_submit").click(function()
- {
- $("#progress").show();
- var formdata = new FormData($("#form")[0]);
- $.ajax({
- url:'/upload',
- type:'post',
- 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('data-value', progress);
- $("#progress").progress('update progress', progress);
- $("#progress").progress('set label', speed + "MB/s");
- }
- };
- return xhr;
- },
- processData:false,
- contentType:false,
- data:formdata,
- success:function (data) {
- $('body').toast({
- title: '恭喜你',
- message: "你已经成功将 《" + $('#button_choose')[0].innerHTML + "》 上传至了武丑兄的机械革命。页面即将自动刷新",
- showProgress: 'bottom',
- classProgress: 'red'
- });
- setTimeout("location.reload();", 3000)
- }
- })
- });
- $('#progress').progress({
- label: 'percent',
- });
- $('a').popup({
- on: 'hover'
- });
- $("#button_submit").popup({
- on: 'hover'
- });
- script>
- 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('/')
- def hello(filelist=[]):
- return render_template("index.html", filelist=get_filelist())
-
- @app.route('/upload',methods=['GET','POST'])
- def upload():
- if request.method == 'POST':
- f = request.files['file']
- 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('/download/
' ,methods=['GET']) - def download(filename):
- response = make_response(send_from_directory("upload", filename, as_attachment=True))
- response.headers["Content-Disposition"] = "attachment; filename={}".format(filename.encode().decode('latin-1'))
- return response
-
- if __name__ == '__main__':
- app.run(host='0.0.0.0', port=80)
界面
本文转载自腾讯博客,转载请注明出处:365文档网