python Flask 寫一個簡易的 web 端上傳文件程序 (附demo)

在撰寫本文時,我將介紹如何使用 Python 的 Flask 框架創建一個簡單的 Web 應用程序,該應用程序允許用戶通過 HTTP POST 請求上傳文件到服務器。Flask 是 Python 中的一個輕量級網絡應用框架,它基於 “Werkzeug WSGI 工具箱” 和 “Jinja2 模板引擎”。以下將逐步指導您完成整個過程,從設置環境到最終部署。

一. 安裝 Flask 和依賴庫

首先,確保您的系統上已經安裝了 Python 3(推薦版本爲 3.6 或更高)。然後可以通過 pip 來安裝 Flask:

pip install flask

此外,我們還需要安裝一些額外的庫以支持文件的上傳功能,例如 `flask-cors` (跨域資源共享) 和 `werkzeug.datastructures.FileStorage` 等。這些可以通過以下命令進行安裝:

pip install flask-cors werkzeug[secure]

二. 創建一個新的 Flask 項目

1. 創建一個新的目錄用於存放我們的項目代碼。

2. 在項目中新建兩個文件:`app.py` 作爲我們的主程序文件;`templates/upload_form.html` 作爲我們的 HTML 模板文件。

三. 編寫 `app.py`

在這個文件中,我們將定義我們的 Flask 應用程序對象以及路由處理函數。以下是基本的骨架代碼:

from flask import Flask, render_template, request, redirect, url_for
import os
from flask_cors import CORS

# 初始化 Flask 應用程序實例
app = Flask(__name__)
CORS(app)  # 啓用跨域資源共享

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

@app.route('/')
def index():
return render_template('upload_form.html')

@app.route('/upload', methods=['POST'])
def upload_file():
if not request.files or not request.method == 'POST':
return redirect(url_for('index'))

uploaded_file = request.files['file']
if uploaded_file and allowed_file(uploaded_file.filename):
filename = secure_filename(uploaded_file.filename)
uploaded_file.save(os.path.join(app.root_path, UPLOAD_FOLDER, filename))
flash('Your file has been successfully uploaded!')
return redirect(url_for('index'))
else:
flash('Please select a valid file to upload.')
return redirect(url_for('index'))

def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def secure_filename(filename):
return re.sub(r'[^A-Za-z0-9\s_-]', '', filename)

if __name__ == "__main__":
try:
os.makedirs(UPLOAD_FOLDER)
except OSError as e:
if e.errno != errno.EEXIST:
raise

app.run(debug=True)

這段代碼包含了幾個關鍵部分:

  • `allowed_file()` 函數檢查上傳文件的擴展名是否在我們的白名單中。
  • `secure_filename()` 函數清理用戶輸入的文件名稱,以防惡意攻擊。
  • `app.run(debug=True)` 語句在開發模式下運行 Flask 應用程序。

四. 編寫 `templates/upload_form.html`

這是我們的 HTML 模板文件,其中包含了一個表單,用來提交要被上傳的文件。請注意,我們需要動態地引用 JavaScript 中的 `CSRF` token,以便正確處理跨站請求僞造保護機制。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Upload File Example</title>
</head>
<body>
<h1>Upload File</h1>
<p>Here you can upload your files securely using the Flask framework.</p>
<div id='content'>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form action="" method=post enctype=multipart/form-data>
<p>
<input type=file name=file required accept=".txt, .pdf, image/*"/>
<input type=submit value=Upload>
</p>
</form>
</div>
<!-- Import csrf protection script -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script>
$(function () {
// Get the CSRF Token from the server
$.getJSON("/" + document.querySelectorAll('base')[0]['href'].replace('/templates/', '/api/csrf/token'), function (json) {
console.log(json); // Should be a JSON object with a key named "token"
var csrftoken = json['token'];
document.getElementById('csrf_header').value = csrftoken;
document.getElementById('csrf_param').value = 'Token ' + csrftoken;
});
})
</script>
</body>
</html>

五. 測試與部署

現在我們可以嘗試啓動我們的應用程序並在瀏覽器中訪問 http://localhost:5000 來進行測試。如果一切正常,你應該會看到一個簡單的網頁和一個可以用來上傳文件的表單。選擇一個合適的文件並點擊“上傳”按鈕,應該能看到成功上傳的信息。

最後,當你對應用程序感到滿意後,你可以考慮將其部署到生產環境中。這可能涉及到配置 HTTPS、負載均衡器、數據庫連接池和其他優化措施。對於初學者來說,Heroku、AWS Elastic Beanstalk 或者 Google App Engine 等雲服務提供商可能是很好的選擇。

請記住,這個例子是爲了演示目的而設計的,在實際的生產環境中可能需要更多的安全性和錯誤處理的措施。比如,你可能想要限制每個用戶的最大文件大小,定期清除舊的上傳文件,以及對上傳的數據進行加密存儲等等。

为您推荐