還在用Python自帶的httpserver?快開感受下更炫酷的Vip版功能吧!

python HttpServer

python2與python3都可以基于SimpleHTTPServer,快速創(chuàng)建一個http服務(wù)器,但方法略有不同。
首先進入你需要設(shè)置的http服務(wù)器目錄 (我以自己電腦路徑:F:/Working~Study) ,即進入到該目錄下,然后:

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

使用方式與樣式都是一樣的,如下圖:


python自帶httpserver.gif

用起來沒問題,但丑出天際...
提單時間到,來說一說有哪些存在的問題吧:

  1. 啟動服務(wù)器后,無登陸限制,任何人都能訪問
  2. 訪問鏈接后,顯示純html頁面,美觀性差,或者說毫無美感可言
  3. 非ansi碼的文本打開,都是亂碼
  4. 文本與pdf等文件點擊時,默認(rèn)打開而非下載
  5. 文件夾與文件的差別僅僅在于是否有末尾/,識別度差
  6. 文件夾與文件的詳細(xì)信息無法獲取(如:創(chuàng)建時間,大小)
  7. 頁面點擊無返回按鈕,只能使用瀏覽器默認(rèn)的前進后退
  8. 默認(rèn)的http只有下載,而沒有上傳功能(這個是硬傷啊!)

既然python自帶的http服務(wù)器,存在這么多的問題,那決不能慣著它,今天咱們就自己重寫一個PythonHttpServer。

FlaskHttpServer

先來看看最終的實現(xiàn)效果:


FlaskHttpServer.gif
  • 安全
    添加了用戶名密碼的登陸限制(簡單寫死了用戶名密碼,可擴展支持?jǐn)?shù)據(jù)庫讀取等方式),這個就不多說了
  • 樣式
    引入了bootstrap的表單樣式,簡潔美觀
  • 下載
    設(shè)置所有文件均直接下載,解決了之前文本等直接打開、并且亂碼的問題
  • 展示
    1. 仿照windows系統(tǒng),添加了名稱、修改時間、文件類型、大小
    2. 優(yōu)化了文件夾、文件等展示方式,并針對兩者進行大小寫的模糊排序,
    3. 針對文件大小,優(yōu)化動態(tài)展示B、KB、MB、GB
  • 頁面跳轉(zhuǎn)
    增加了首頁,與子路徑的快捷鍵訪問,每一層的路徑均可做為鏈接進行跳轉(zhuǎn)
設(shè)計方案
  1. 使用藍圖構(gòu)建項目
    雖然目前僅存在賬戶管理與頁面展示和下載兩個模塊,但使用藍圖的目的是為了便于擴展,后期有空了還可以實現(xiàn)下上傳功能。
    整體目錄如下:


    項目目錄
  2. 針對目錄展示
    獲取path后,先獲取os.listdir()結(jié)果進行排序:
    sorted(os.listdir('.'), key=lambda x: x.lower())
    再將目錄分為兩個列表(文件夾、文件),并針對類型不同,分別獲取不同數(shù)據(jù),方法如下:

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 '%d  B' % 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))
  1. 在app中創(chuàng)建自定義過濾器,將所有路徑進行拆分,生成子路徑及對應(yīng)的path進行跳轉(zhuǎn)
    @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

因為涉及的文件比較多,就不一個個的往上貼了,如果大家對這個小項目感興趣,可以公眾號回復(fù)關(guān)鍵字[服務(wù)器]獲取源碼....

上傳功能之模態(tài)框

使用bootstrap實現(xiàn)點擊按鈕彈出窗口,簡直不要太簡單。我們只需要將寫好的窗口內(nèi)容隱藏,然后調(diào)用bootstrap的框架即可,簡單幾行就能完成相關(guān)功能實現(xiàn)....
前提條件是,我們需要引入bootstrap.min.js,直接上代碼看下準(zhǔn)備好的上傳文件彈框吧....

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"> 
    <title>Bootstrap 實例 - 模態(tài)框(Modal)插件</title>
    <link rel="stylesheet" >
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<h2>創(chuàng)建模態(tài)框(Modal)</h2>
<!-- 按鈕觸發(fā)模態(tài)框 -->
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
    文件上傳
</button>
<!-- 模態(tài)框(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">關(guān)閉</button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal -->
</div>
</body>
</html>
bootstrap模態(tài)框.gif
jQuery事件與ajax

正常情況下,我們使用form表單進行上傳文件,需要在表單內(nèi)部添加一個type="submit"的按鈕,可如何才能像demo示例中的,將上傳按鈕置于頁面的任何位置來控制上傳呢?有jQuery在,就很簡單...

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

由于是彈出窗口,我們選擇文件后,點擊上傳,此時如果使用url_for()進行頁面跳轉(zhuǎn),有些不符合使用習(xí)慣,那么再加深一點,引入ajax進行異步提交好了,那么全量的點擊事件就變?yōu)椋?/p>

<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>
關(guān)于js中使用Jinjia2

在js中直接使用jinjia2的模板引擎會報錯...比如這樣:alert({{Book}});,那么該怎么處理?

  • bad
    將內(nèi)容寫在html中,然后通過js去獲?。?/li>
<p id="upload_path" style="display:none">{{path}}</p>
var upload_path = $('#upload_path').text();
  • good
    通過jinjia2的tojson過濾器,可以將變量轉(zhuǎn)為json字符串
    var upload_path = {{path|tojson|safe}};
最終上傳實現(xiàn)

軟件整體效果如下:


Flask_Httpserver.gif
The End

今天的內(nèi)容就到這里,歡迎關(guān)注我的微信公眾號【清風(fēng)Python】謝謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容