替代cgi.FieldStorage读取表单上传文件内容的Python代码方案
替代CGI模块处理文件上传的方案
问题说明
Python的cgi模块即将被移除,需要替换原有处理文件上传的代码。当前使用的HTML上传表单如下:
<form id="uploadfile" method="post" action="cgi-bin/getfile.py"> <p> Filename: <input type="file" device="files" name="srcfile" size="55" value="" /> </p> ... <input type="submit" value="Submit"> </form>
原有基于cgi模块的可行代码:
import cgi form = cgi.FieldStorage() fileitem = form['srcfile'] contents = fileitem.file.read()
尝试使用urllib.parse.parse_qs仅能获取表单字段字典,无法读取上传文件的实际内容:
from urllib.parse import parse_qs form = parse_qs(qs, encoding="utf-8") filename = form['srcfile'][0]
不清楚multipart.multipart.FormParser()的具体用法,需要找到cgi模块的替代方案。
方案1:使用multipart模块的FormParser
先通过pip install multipart安装第三方multipart库,之后可以用FormParser直接解析multipart/form-data格式的请求体,示例代码如下:
import sys from multipart import FormParser, Field def process_uploaded_file(field: Field): if field.is_file and field.name == 'srcfile': # 获取上传文件名 print(f"上传文件名称: {field.filename}") # 读取文件内容 file_content = field.raw.read() # 此处可添加内容处理逻辑,比如保存到本地 # with open(field.filename, 'wb') as f: # f.write(file_content) return file_content # 从环境变量和标准输入获取请求数据 content_length = int(sys.environ.get('CONTENT_LENGTH', 0)) request_body = sys.stdin.read(content_length) content_type = sys.environ.get('CONTENT_TYPE', '') # 初始化解析器并处理字段 parser = FormParser(request_body, content_type) for field in parser: if field.name == 'srcfile': file_content = process_uploaded_file(field) # file_content即为原cgi代码中读取的文件内容
方案2:使用标准库email模块解析
无需额外安装依赖,使用Python标准库的email模块即可解析multipart/form-data请求,示例如下:
import sys import email from email.message import Message # 获取请求相关数据 content_length = int(sys.environ.get('CONTENT_LENGTH', 0)) request_body = sys.stdin.read(content_length) content_type = sys.environ.get('CONTENT_TYPE', '') # 构建Message对象用于解析 msg = Message() msg['Content-Type'] = content_type msg.set_payload(request_body) # 遍历解析各表单部分 for part in msg.get_payload(): disp = part.get_content_disposition() if disp == 'form-data': field_name = part.get_param('name') if field_name == 'srcfile': # 获取文件名 filename = part.get_param('filename') # 读取文件内容(decode=True自动处理编码) file_content = part.get_payload(decode=True) print(f"已读取文件 {filename} 的内容") # 后续处理逻辑写在这里
内容的提问来源于stack exchange,提问作者sjizma
相关产品推荐
相关产品推荐

