Python Flask 极速上手:搭建图片上传 Web 服务,安全又高效
28
0
0
0
准备工作
搭建 Flask 应用
测试图片上传
安全注意事项
完整代码
总结
想要快速搭建一个能够接收图片上传并保存的 Web 服务吗?Python 的 Flask 框架绝对是你的不二之选!它轻量级、灵活,上手简单,能让你在短时间内实现所需功能。本文将带你一步步使用 Flask 框架创建一个简单的 Web 服务器,可以接收客户端上传的图片,并将图片保存到服务器的指定目录,最后返回一个成功的消息。
准备工作
在开始之前,请确保你已经安装了 Python 和 pip。然后,使用 pip 安装 Flask 框架:
pip install Flask
搭建 Flask 应用
创建项目目录: 首先,创建一个目录来存放你的项目文件。例如,创建一个名为
image_upload
的目录。
mkdir image_upload
cd image_upload
2. **创建 Flask 应用文件:** 在项目目录下,创建一个名为 `app.py` 的 Python 文件。这是 Flask 应用的核心文件。 ```python from flask import Flask, request, jsonify import os from werkzeug.utils import secure_filename app = Flask(__name__) # 配置图片上传目录 UPLOAD_FOLDER = 'uploads' app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # 允许上传的图片类型 ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} # 确保上传目录存在 if not os.path.exists(UPLOAD_FOLDER): # 检查目录是否存在,不存在则创建 os.makedirs(UPLOAD_FOLDER) # 检查文件扩展名是否在允许范围内 def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/upload', methods=['POST']) def upload_file(): if 'file' not in request.files: return jsonify({'error': 'No file part'}) file = request.files['file'] if file.filename == '': return jsonify({'error': 'No selected file'}) if file and allowed_file(file.filename): filename = secure_filename(file.filename) # 使用 secure_filename 确保文件名安全 file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return jsonify({'message': 'File uploaded successfully', 'filename': filename}) else: return jsonify({'error': 'Invalid file type'}) # 更明确的错误信息 if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000) ``` 3. **代码解析:** * **导入必要的库:** `Flask` 用于创建 Web 应用, `request` 用于处理客户端请求, `jsonify` 用于将 Python 对象转换为 JSON 格式,`os` 用于处理文件路径, `secure_filename` 用于安全地获取文件名。 * **创建 Flask 应用实例:** `app = Flask(__name__)` 创建一个 Flask 应用实例。 * **配置上传目录:** `UPLOAD_FOLDER = 'uploads'` 定义上传目录为 `uploads`。`app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER` 将上传目录配置到 Flask 应用中。如果 uploads 文件夹不存在,使用 `os.makedirs(UPLOAD_FOLDER)` 创建该文件夹。 * **配置允许的文件类型:** `ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}` 定义允许上传的文件类型。 * **`allowed_file` 函数:** 这个函数检查上传的文件名是否具有允许的扩展名。 * **`upload_file` 路由:** * `@app.route('/upload', methods=['POST'])` 定义一个路由 `/upload`,只允许 POST 请求。 * `request.files['file']` 获取上传的文件。 * 检查是否有文件上传,文件名是否为空,以及文件类型是否允许。 * `secure_filename(file.filename)` 使用 `secure_filename` 函数来确保文件名的安全性,防止恶意用户上传包含恶意代码的文件。 * `file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))` 将文件保存到指定的上传目录。 * 返回一个 JSON 格式的成功消息,包含文件名。 * **运行 Flask 应用:** `app.run(debug=True, host='0.0.0.0', port=5000)` 运行 Flask 应用。`debug=True` 开启调试模式,方便开发;`host='0.0.0.0'` 允许所有 IP 访问, `port=5000` 指定端口为 5000。 ## 运行 Flask 应用 在命令行中,进入项目目录,然后运行 `app.py` 文件: ```bash python app.py
你会看到类似下面的输出:
* Serving Flask app 'app' * Debug mode: on * Running on all addresses (0.0.0.0) WARNING: This is a development server. Do not use it in a production deployment. * Running on http://127.0.0.1:5000 * Running on http://192.168.1.100:5000 (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 123-456-789
这表示你的 Flask 应用已经在 http://127.0.0.1:5000
启动了。
测试图片上传
你可以使用 curl 命令或者 Postman 等工具来测试图片上传功能。
使用 curl 命令:
curl -X POST -F file=@/path/to/your/image.jpg http://127.0.0.1:5000/upload
将 /path/to/your/image.jpg
替换为你本地图片文件的路径。
使用 Postman:
- 创建一个新的 POST 请求,URL 设置为
http://127.0.0.1:5000/upload
。 - 在 Body 选项卡中,选择
form-data
。 - 添加一个 key,名为
file
,Type 选择File
,然后选择你要上传的图片文件。 - 点击 Send 按钮发送请求。
如果上传成功,你会收到类似下面的 JSON 响应:
{ "filename": "image.jpg", "message": "File uploaded successfully" }
同时,你可以在 uploads
目录下看到上传的图片文件。
安全注意事项
虽然我们已经使用 secure_filename
函数来保护文件名,但仍然需要注意以下安全问题:
- 文件类型验证: 始终验证上传文件的类型,确保它是你期望的图片类型。仅仅依赖文件扩展名是不够的,可以使用 Python 的
PIL
(Pillow) 库来验证图片文件的内容。 - 文件大小限制: 限制上传文件的大小,防止恶意用户上传过大的文件,导致服务器资源耗尽。可以在 Flask 应用中配置
MAX_CONTENT_LENGTH
。 - 上传目录权限: 确保上传目录的权限设置正确,只允许 Web 服务器进程写入,防止恶意用户通过上传漏洞执行任意代码。
- 防止目录遍历: 避免使用用户提供的文件名直接拼接成文件路径,防止目录遍历漏洞。始终使用
os.path.join
来拼接文件路径。
完整代码
from flask import Flask, request, jsonify import os from werkzeug.utils import secure_filename app = Flask(__name__) # 配置图片上传目录 UPLOAD_FOLDER = 'uploads' app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # 允许上传的图片类型 ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} # 确保上传目录存在 if not os.path.exists(UPLOAD_FOLDER): os.makedirs(UPLOAD_FOLDER) # 检查文件扩展名是否在允许范围内 def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/upload', methods=['POST']) def upload_file(): if 'file' not in request.files: return jsonify({'error': 'No file part'}) file = request.files['file'] if file.filename == '': return jsonify({'error': 'No selected file'}) if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return jsonify({'message': 'File uploaded successfully', 'filename': filename}) else: return jsonify({'error': 'Invalid file type'}) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000)
总结
本文介绍了如何使用 Python 的 Flask 框架快速搭建一个简单的图片上传 Web 服务。通过学习本文,你不仅掌握了 Flask 的基本用法,还了解了如何处理文件上传以及一些常见的安全注意事项。希望你能利用这些知识,构建出更强大、更安全的 Web 应用!以后上传小姐姐的照片再也不用求别人啦,哈哈!