在Python中实现文件上传到服务器是常见的开发需求,通常涉及客户端(Python脚本)和服务器端(如Flask、Django框架或Node.js等)的协同工作,以下是详细的实现步骤和注意事项,涵盖客户端上传逻辑、服务器端接收处理及错误处理等内容。

客户端上传实现
客户端使用Python上传文件,主要通过requests库模拟HTTP POST请求,或使用ftplib库通过FTP协议上传,以下是两种方式的示例:
使用requests库(HTTP协议)
首先安装requests库:pip install requests,假设服务器端有一个接收文件的接口(如Flask的/upload),客户端代码如下:
import requests
file_path = "example.txt" # 本地文件路径
url = "http://服务器IP:端/upload" # 服务器接收接口
with open(file_path, "rb") as f:
files = {"file": (file_path, f)} # 构造文件数据
response = requests.post(url, files=files) # 发送POST请求
if response.status_code == 200:
print("上传成功:", response.text)
else:
print("上传失败:", response.status_code)
关键参数说明:
files参数:字典类型,键为服务器端期望的表单字段名(如file),值为文件对象和文件名。headers:可添加认证信息(如{"Authorization": "Bearer token"})。timeout:设置超时时间(如timeout=30),避免长时间阻塞。
使用ftplib库(FTP协议)
若服务器支持FTP,需安装ftplib(Python内置库),示例代码:

from ftplib import FTP
ftp = FTP("服务器IP")
ftp.login("用户名", "密码") # 登录FTP服务器
file_path = "example.txt"
with open(file_path, "rb") as f:
ftp.storbinary("STOR " + file_path, f) # 上传文件
ftp.quit() # 关闭连接
注意事项:
- FTP传输需确保服务器开放21端口(默认)及被动模式(
ftp.set_pasv(True))。 - 不适合大文件传输,且安全性较低(建议使用SFTP/FTPS)。
服务器端接收处理
以Flask框架为例,服务器端需配置路由和文件保存逻辑,首先安装Flask:pip install Flask,代码如下:
from flask import Flask, request
app = Flask(__name__)
@app.route("/upload", methods=["POST"])
def upload_file():
if "file" not in request.files:
return "未选择文件", 400
file = request.files["file"]
if file.filename == "":
return "文件名为空", 400
if file: # 检查文件是否合法
save_path = "uploads/" + file.filename # 保存路径
file.save(save_path) # 保存文件
return f"文件已保存至: {save_path}", 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000) # 监听所有IP
关键配置:
- 文件保存目录需提前创建(如
mkdir uploads),并设置写权限。 - 可通过
app.config["MAX_CONTENT_LENGTH"]限制上传文件大小(默认16MB)。 - 安全性:检查文件扩展名、病毒扫描,避免上传恶意文件。
常见问题与解决方案
错误处理
- 文件过大:服务器端需设置
MAX_CONTENT_LENGTH,客户端可分片上传(如使用tus协议)。 - 网络中断:客户端实现断点续传(通过
requests的headers传递Range字段)。 - 权限问题:确保服务器目录权限为755(Linux),或使用
os.chmod调整权限。
性能优化
- 多线程/异步:服务器端使用
Flask + Gunicorn或FastAPI提高并发能力。 - 压缩传输:客户端在上传前压缩文件(如
gzip),减少流量消耗。
相关问答FAQs
Q1: 如何在上传时显示进度条?
A: 使用tqdm库结合requests实现进度显示,示例代码:

from tqdm import tqdm
import requests
file_path = "large_file.zip"
with open(file_path, "rb") as f, tqdm(unit="B", unit_scale=True, unit_divisor=1024, miniters=1, desc=file_path) as progress_bar:
files = {"file": (file_path, f)}
response = requests.post(url, files=files, hooks={"response": lambda r, *args, **kwargs: progress_bar.update()})
Q2: 服务器端如何限制上传文件类型?
A: 通过检查文件扩展名或MIME类型实现,例如在Flask中:
ALLOWED_EXTENSIONS = {".txt", ".pdf", ".png"}
def allowed_file(filename):
return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS
在路由中调用allowed_file(file.filename)判断,若不符合则返回错误。
