<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### 導航 - [索引](# "總目錄") - [下一頁](# "緩存") | - [上一頁](# "在 Flask 中使用 SQLAlchemy") | - [Flask 0.10.1 文檔](#) ? - [Flask 代碼模式](#) ? # 上傳文件 哦,上傳文件可是個經典的好問題了。文件上傳的基本概念實際上非常簡單,他基本是這樣工作的: 1. 一個 <form> 標簽被標記有 enctype=multipart/form-data ,并且在里面包含一個 <inputtype=file> 標簽。 1. 服務端應用通過請求對象上的 files 字典訪問文件。 1. 使用文件的 [save()](http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage.save "(在 Werkzeug v0.10)") [http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage.save] 方法將文件永久地保存在文件系統上的某處。 ### 一點點介紹 讓我們建立一個非常基礎的小應用,這個小應用可以上傳文件到一個指定的文件夾里,然后將這個文件顯示給用戶。讓我們看看這個應用的基礎代碼: ~~~ import os from flask import Flask, request, redirect, url_for from werkzeug import secure_filename UPLOAD_FOLDER = '/path/to/the/uploads' ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) app = Flask(__name__) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER ~~~ 首先我們導入一些東西,大多數內容都是直接而容易的。werkzeug.secure_filename()將會在稍后進行解釋。 UPLOAD_FOLDER 是我們儲存上傳的文件的地方,而 ALLOWED_EXTENSIONS則是允許的文件類型的集合。然后我們手動為應用添加一個的 URL 規則。我們通常很少這樣做,但是為什么這里要如此呢?原因是我們希望實際部署的服務器(或者我們的開發服務器)來為我們提供這些文件的訪問服務,所以我們只需要一個規則用來生成指向這些文件的 URL 。 為什么我們限制上傳文件的后綴呢?您可能不希望您的用戶能夠上傳任何文件到服務器上,如果服務器直接將數據發送給客戶端。以這種方式,您可以確保您的用戶不能上傳可能導致 XSS 問題(參考 [*跨站腳本攻擊(XSS)*](#) )的 HTML 文件。也確保會阻止 .php 文件以防其會被運行。當然,誰還會在服務器上安裝PHP 啊,是不是? :) 下一步,就是檢查文件類型是否有效、上傳通過檢查的文件、以及將用戶重定向到已經上傳好的文件 URL 處的函數了: ~~~ def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS @app.route('/', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': file = request.files['file'] if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return redirect(url_for('uploaded_file', filename=filename)) return ''' <!doctype html> <title>Upload new File</title> <h1>Upload new File</h1> <form action="" method=post enctype=multipart/form-data> <p><input type=file name=file> <input type=submit value=Upload> </form> ''' ~~~ 那么 [secure_filename()](http://werkzeug.pocoo.org/docs/utils/#werkzeug.utils.secure_filename "(在 Werkzeug v0.10)") [http://werkzeug.pocoo.org/docs/utils/#werkzeug.utils.secure_filename] 函數具體做了那些事呢?現在的問題是,有一個信條叫做“永遠別相信你用戶的輸入” ,這句話對于上傳文件的文件名也是同樣有效的。所有提交的表單數據都可以偽造,而文件名本身也可能是危險的。在攝氏只需記住:在將文件保存在文件系統之前,要堅持使用這個函數來確保文件名是安全的。 關于文件名安全的更多信息 您對 [secure_filename()](http://werkzeug.pocoo.org/docs/utils/#werkzeug.utils.secure_filename "(在 Werkzeug v0.10)") [http://werkzeug.pocoo.org/docs/utils/#werkzeug.utils.secure_filename] 的具體工作和您沒使用它會造成的后果感興趣?試想一個人可以發送下列信息作為 filename 給您的應用: ~~~ filename = "../../../../home/username/.bashrc" ~~~ 假定 ../ 的數量是正確的,而您會將這串字符與 UPLOAD_FOLDER 所指定的路徑相連接,那么這個用戶就可能有能力修改服務器文件系統上的一個文件,而他不應該擁有這種權限。這么做需要一些關于此應用情況的技術知識,但是相信我,駭客們都有足夠的耐心 :) 現在我們來研究一下這個函數的功能: ~~~ >>> secure_filename('../../../../home/username/.bashrc') 'home_username_.bashrc' ~~~ 現在還有最后一件事沒有完成: 提供對已上傳文件的訪問服務。 在 Flask 0.5以上的版本我們可以使用一個函數來實現此功能: ~~~ from flask import send_from_directory @app.route('/uploads/<filename>') def uploaded_file(filename): return send_from_directory(app.config['UPLOAD_FOLDER'], filename) ~~~ 或者,您也可以選擇為 uploaded_file 注冊 build_only 規則,然后使用[SharedDataMiddleware](http://werkzeug.pocoo.org/docs/middlewares/#werkzeug.wsgi.SharedDataMiddleware "(在 Werkzeug v0.10)") [http://werkzeug.pocoo.org/docs/middlewares/#werkzeug.wsgi.SharedDataMiddleware] 類來實現下載服務。這種方法同時支持更老版本的 Flask: ~~~ from werkzeug import SharedDataMiddleware app.add_url_rule('/uploads/<filename>', 'uploaded_file', build_only=True) app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/uploads': app.config['UPLOAD_FOLDER'] }) ~~~ 運行應用,不出意外的話,一切都應該像預期那樣工作了。 ### 改進上傳功能 0.6 新版功能. Flask 到底是如何處理上傳的呢?如果服務器相對較小,那么他會先將文件儲存在網頁服務器的內存當中。否則就將其寫入一個臨時未知(如函數 [tempfile.gettempdir()](http://docs.python.org/dev/library/tempfile.html#tempfile.gettempdir "(在 Python v3.5)") [http://docs.python.org/dev/library/tempfile.html#tempfile.gettempdir]返回的路徑)。但是怎么指定一個文件大小的上限,當文件大于此限制,就放棄上傳呢? 默認 Flask 會很歡樂地使用無限制的空間,但是您可以通過在配置中設定MAX_CONTENT_LENGTH 鍵的值來限制它: ~~~ from flask import Flask, Request app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 ~~~ 上面的代碼將會把上傳文件限制為最大 16 MB 。 如果請求傳輸一個更大的文件,Flask 會拋出一個 [RequestEntityTooLarge](http://werkzeug.pocoo.org/docs/exceptions/#werkzeug.exceptions.RequestEntityTooLarge "(在 Werkzeug v0.10)") [http://werkzeug.pocoo.org/docs/exceptions/#werkzeug.exceptions.RequestEntityTooLarge] 異常。 這個特性是在 Flask 0.6 中被加入的,但是更老的版本也可以通過構建請求對象的子類來實現。更多信息請查詢 Werkzeug 文檔中文件處理部分的內容。 ### 上傳進度條 以前,很多開發者實現進度條的方法是這樣的: 一邊小塊小塊地讀取傳輸來的文件,一邊將上傳進度儲存在數據庫中,然后在通過客戶端的 JavaScript 代碼讀取進度。簡單來說,客戶端會每5秒鐘詢問服務器傳輸的進度。您感覺到這種諷刺了么?客戶端詢問一些他本應該已經知道的事情。 現在有了一些性能更好、運行更可靠的解決方案。WEB 已經有了不少變化,現在您可以使用 HTML5、Java、Silverlight 或者 Flash 來實現客戶端更好的上傳體驗。看一看下面列出的庫的連接,可以找到一些很好的樣例。 - [Plupload](http://www.plupload.com/) [http://www.plupload.com/] - HTML5, Java, Flash - [SWFUpload](http://www.swfupload.org/) [http://www.swfupload.org/] - Flash - [JumpLoader](http://jumploader.com/) [http://jumploader.com/] - Java ### 更簡單解決方案 因為存在一個處理上傳文件的范式,這個范式在大多數應用中機會不會有太大改變,所以 Flask 存在一個擴展名為 [Flask-Uploads](http://packages.python.org/Flask-Uploads/) [http://packages.python.org/Flask-Uploads/] ,這個擴展實現了一整套成熟的文件上傳架構。它提供了包括文件類型白名單、黑名單等多種功能。 ? 版權所有 2013, Armin Ronacher.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看