还在用Python自带的 httpserver?快开感受下更炫酷的Vip版功能吧

python2与python3都可以基于Simple HTTP Server,快速创建一个http服务器,但方法略有不同。

首先进入你需要设置的http服务器目录 (我以自己电脑路径: F:/Working~Study ) ,即进入到该目录下,然后:

python2:python -m SimpleHTTPServer 8888python3:python -m http.server 8888

使用方式与样式都是一样的,如下图:

用起来没问题,但丑出天际…

提单时间到,来说一说有哪些存在的问题吧:

启动服务器后,无登陆限制,任何人都能访问访问链接后,显示纯html页面,美观性差,或者说毫无美感可言非ansi码的文本打开,都是乱码文本与pdf等文件点击时,默认打开而非下载文件夹与文件的差别仅仅在于是否有末尾/,识别度差文件夹与文件的详细信息无法获取(如:创建时间,大小)页面点击无返回按钮,只能使用浏览器默认的前进后退默认的http只有下载,而没有上传功能(这个是硬伤啊! )

既然python自带的http服务器,存在这么多的问题,那决不能惯着它,今天咱们就自己重写一个PythonHttpServer

VIP HttpServer

先来看看最终的实现效果 :

FlaskHttpServer.gif

简单的安全验证添加了用户名密码的登陆限制(简单写死了用户名密码,当然可扩展支持数据库读取等方式),这个就不多说了美化样式引入了bootstrap的表单样式,简洁美观下载调优设置所有文件均直接下载,解决了之前文本等直接打开、并且乱码的问题上传功能jQuery配合Ajax,加上bootstrap的模态框,轻松完成上传功能。展示优化仿照windows系统,添加了名称、修改时间、文件类型、大小优化了文件夹、文件等展示方式,并针对两者进行大小写的模糊排序,针对文件大小,优化动态展示B、KB、MB、GB页面跳转增加了首页,与子路径的快捷键访问,每一层的路径均可做为链接进行跳转

设计方案

使用蓝图构建项目

虽然目前仅存在账户管理与页面展示和下载两个模块,但使用蓝图的目的是为了便于扩展,后期有空了还可以实现下上传功能。

整体目录如下:

项目目录

针对目录展示

获取path后,先获取os.listdir()结果进行排序:

sorted(os.listdir(.), key=lambda x: x.lower())

再将目录分为两个列表(文件夹、文件),并针对类型不同,分别获取不同数据,方法如下:

class DocumentReader: def __init__(self, real_path): self.real_path = real_path def analysis_dir(self): dirs = [] files = [] os.chdir(self.real_path) for name in sorted(os.listdir(.), key=lambda x: x.lower()): _time = time.strftime("%Y/%m/%d %H:%M", time.localtime(os.path.getctime(name))) if os.path.isdir(name): dirs.append([name, _time, 文件夹, -]) elif os.path.isfile(name): file_type = os.path.splitext(name)[1] size = self.get_size(os.path.getsize(name)) files.append([name, _time, file_type, size]) return dirs, files @staticmethod def get_size(size): if size < 1024: return %dB % size elif 1024 <= size < 1024 * 1024: return %.2f KB % (size / 1024) elif 1024 * 1024 <= size < 1024 * 1024 * 1024: return %.2f MB % (size / (1024 * 1024)) else: return %.2f GB % (size / (1024 * 1024 * 1024))

创建自定义过滤器

将所有路径进行拆分,生成子路径及对应的path进行跳转

@app.template_filter("split_path") def split_path(path): path_list = path.split(/) path_list = [[path_list[i - 1], /.join(path_list[:i])] for i in range(1, len(path_list)+1)] return path_list

因为涉及的文件比较多,就不一个个的往上贴了,如果大家对这个小项目感兴趣,可以回复关键字 [服务器] 获取源码….

上传功能之模态框

使用bootstrap实现点击按钮弹出窗口,简直不要太简单。我们只需要将写好的窗口内容隐藏,然后调用bootstrap的框架即可,简单几行就能完成相关功能实现….

前提条件是,我们需要引入bootstrap.min.js,直接上代码看下准备好的上传文件弹框吧….

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Bootstrap 实例 - 模态框(Modal)插件</title> <link rel="stylesheet" href=""> <script src=""></script> <script src=""></script> </head> <body> <h2>创建模态框(Modal)</h2> <!-- 按钮触发模态框 --> <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> 文件上传 </button> <!-- 模态框(Modal) --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title" id="myModalLabel"> 请选择所需上传的本地文件 </h4> </div> <div class="modal-body"> <form id="upload-form" enctype="multipart/form-data"> <input id=file class="btn btn-info" name="upload_file" type="file"> </form> </div> <div class="modal-footer"> <button id=upload class="btn btn-primary ">上传</button> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal --> </div> </body> </html>

bootstrap模态框.gif

私信小编

jQuery事件与ajax

正常情况下,我们使用form表单进行上传文件,需要在表单内部添加一个 type="submit" 的按钮,可如何才能像demo示例中的,将上传按钮置于页面的任何位置来控制上传呢?有jQuery在,就很简单…

<script> $(#upload) .click(function() { $(#upload).submit(); }) </script>

由于是弹出窗口,我们选择文件后,点击上传,此时如果使用url_for()进行页面跳转,有些不符合使用习惯,那么再加深一点,引入ajax进行异步提交好了,那么全量的点击事件就变为:

<script> $(#upload).click(function() { var upload_path = $(#upload_path).text(); var formData = new FormData($(#upload-form)[0]); formData.append("upload_path", upload_path); $.post({ url: /upload, dataType: json, type: POST, data: formData, async: true, cashe: false, contentType: false, processData: false, success: function(returndata) { if (returndata[code] == 200) { var info = returndata[info] alert(info); } }, error: function(returndata) { alert("上传失败!") } }) }); </script>

关于js中使用Jinjia2

在js中直接使用jinjia2的模板引擎会报错…比如这样: alert({{Book}}); ,那么该怎么处理?

Bad

将内容写在html中,然后通过js去获取:

<p id="upload_path" style="display:none">{{path}}</p> var upload_path = $(#upload_path).text();

Good

通过jinjia2的tojson过滤器,可以将变量转为json字符串:

var upload_path = {{path|tojson|safe}};

最终上传实现