js大文件分块上传与tornado接收文件和下载

将文件分块上传使用的是HTML5的功能(IE可能不支持)

<div class="layui-container">
 <input type="file" id="file" multiple required>
 <br>
 <div class="layui-progress layui-progress-big" lay-filter="demo">
 <div class="layui-progress-bar layui-bg-green"></div>
 </div>
 <br>
 <button class="layui-btn btnFile">立即提交</button>
 <script type="text/javascript">
 var element = layui.element;
 var time = new Date().getTime();
 var upload = function (file, num) {
 var formData = new FormData();
 var blockSize = 1024 * 1024 * 2;
 var blockNum = Math.ceil(file.size / blockSize);
 var nextSize = Math.min(num * blockSize, file.size);
 var fileData = file.slice((num - 1) * blockSize, nextSize);
 formData.append("file", fileData);
 formData.append("fileName", file.name);
 $.ajax({
 url: "",
 type: "POST",
 data: formData,
 processData: false,
 contentType: false,
 success: function (responseText) {
 element.progress('demo', ((num * 100) / blockNum) + '%');
 if (file.size <= nextSize) {
 layer.msg("上传成功");
 return;
 }
 upload(file, ++num);//递归调用
 }
 });
 };
 $(".btnFile").click(function () {
 var file = $("#file")[0].files[0];
 upload(file, 1);
 });
 </script>
</div>

tornado接收

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
 
import tornado.ioloop
import tornado.web
import os
 
class UploadFileHandler(tornado.web.RequestHandler):
 def get(self):
 self.write('''
 <html>
 <head><title>Upload File</title></head>
 <body>
 <form action='file' enctype="multipart/form-data" method='post'>
 <input type='file' name='file'/><br/>
 <input type='submit' value='submit'/>
 </form>
 </body>
 </html>
 ''')
 
 def post(self):
 #文件的暂存路径
 upload_path=os.path.join(os.path.dirname(__file__),'files') 
 #提取表单中‘name’为‘file’的文件元数据
 file_metas=self.request.files['file'] 
 for meta in file_metas:
 filename=meta['filename']
 filepath=os.path.join(upload_path,filename)
 #有些文件需要已二进制的形式存储,实际中可以更改
 with open(filepath,'wb') as up: 
 up.write(meta['body'])
 self.write('finished!')
 
app=tornado.web.Application([
 (r'/file',UploadFileHandler),
])
 
if __name__ == '__main__':
 app.listen(3000)
 tornado.ioloop.IOLoop.instance().start()

在js中构建表单发起下载文件请求

tornado中响应如下:

def post(self,filename):
 print('i download file handler : ',filename)
 #Content-Type这里我写的时候是固定的了,也可以根据实际情况传值进来
 self.set_header ('Content-Type', 'application/octet-stream')
 dispositionName='attachment; filename='+filename
 #因为文件名可能有中文,会出现问题
 dispositionName.encode()
 self.set_header ('Content-Disposition', dispositionName)
 #读取的模式需要根据实际情况进行修改
 buff = 1024 * 1024 * 2
 with open(filename, 'rb') as f:
 while True:
 data = f.read(buff)
 if not data:
 break
 self.write(data)
 #记得有finish哦
 self.finish()

js大文件分块上传与tornado接收文件和下载

相关推荐