Python Flask接口接收Postman上传文件时如何获取原始文件名?
文件名获取方案对比与最优选择
你目前想到的将文件名放在URL路径中传递的方案是可用的,是否是最优方案取决于你的实际使用场景,以下是三种常用方案的对比和实现参考:
方案1:URL路径传递文件名(你当前的思路)
- 优势:实现成本最低,不需要额外解析逻辑,和你当前直接读取
request.stream的写法完全兼容,没有额外性能开销 - 劣势:文件名包含中文、特殊字符(如
/、空格、特殊符号)时需要提前做URL编码,否则会出现解析异常,且无法同步传递其他文件元数据 - 注意事项:必须做文件名安全校验,避免路径遍历攻击,参考实现如下:
import os from flask import request, jsonify @app.route('/uploadFile/<string:filename>', methods=['PUT']) def uploadFile(filename): # 安全处理:只取文件名部分,过滤路径字符,避免用户传入../../xxx这类恶意路径 safe_filename = os.path.basename(filename) chunk_size = 4096 save_path = os.path.join("/Users/xyz/Documents/", safe_filename) with open(save_path, 'wb') as f: while True: chunk = request.stream.read(chunk_size) if len(chunk) == 0: break f.write(chunk) return jsonify({"success":"File transfer initiated", "saved_as": safe_filename})
方案2:自定义请求头传递文件名
客户端把原始文件名放在自定义请求头(如X-File-Name)中传递,不需要修改接口路径规则:
- 优势:不占用URL路径位,同样兼容你当前的流读取逻辑,不需要修改接口路由定义
- 劣势:特殊字符同样需要做URL编码,部分反向代理可能会默认丢弃自定义请求头,需要提前适配
- 参考实现:
import os import urllib.parse from flask import request, jsonify @app.route('/uploadFile', methods=['PUT']) def uploadFile(): raw_filename = request.headers.get('X-File-Name') if not raw_filename: return jsonify({"error": "Missing filename in request header"}), 400 # 解码URL编码的文件名 filename = urllib.parse.unquote(raw_filename) safe_filename = os.path.basename(filename) chunk_size = 4096 save_path = os.path.join("/Users/xyz/Documents/", safe_filename) with open(save_path, 'wb') as f: while True: chunk = request.stream.read(chunk_size) if len(chunk) == 0: break f.write(chunk) return jsonify({"success":"File transfer initiated", "saved_as": safe_filename})
方案3:标准multipart/form-data格式上传
这是HTTP协议规定的文件上传标准实现,Postman等工具原生支持,Flask可直接读取文件对象自带的文件名属性:
- 优势:符合通用标准,不需要手动处理文件名编码,可同时传递多个文件和其他额外参数,兼容性最好
- 劣势:不能直接读取原始
request.stream,需要调整大文件上传的配置限制 - 参考实现:
import os from flask import request, jsonify # 可根据需求调整为PUT方法,客户端对应修改请求方法即可 @app.route('/uploadFile', methods=['POST']) def uploadFile(): if 'file' not in request.files: return jsonify({"error": "No file part"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "No selected file"}), 400 safe_filename = os.path.basename(file.filename) save_path = os.path.join("/Users/xyz/Documents/", safe_filename) file.save(save_path) return jsonify({"success":"File uploaded", "saved_as": safe_filename})
最优选择建议
- 如果是内部服务使用、客户端完全可控,路径传参的方案足够简单高效,是最优选择
- 如果需要对外提供服务、兼容多类客户端,优先选择multipart/form-data的标准方案
- 如果不想修改接口路径规则,且不需要额外参数,选择请求头传参的方案即可
内容的提问来源于stack exchange,提问作者PSD
相关产品推荐
相关产品推荐

