基于Python和Flask开发读取文本文件的RESTful API技术咨询
文本文件读取功能问题排查与正确实现方案
咱们先梳理下你这段Flask代码里的问题,再给你一个规范的RESTful API实现:
🔍 原代码的核心问题
- 错误处理上传文件对象:
request.files['file']拿到的是Werkzeug的FileStorage实例,不是本地文件路径,直接传给open()肯定会报错,这是最主要的问题。 - 缺少请求合法性校验:如果请求里没带文件、或者键名不是
file,代码会直接抛出KeyError,没有友好的错误提示。 - 安全隐患:虽然导入了
secure_filename但没实际使用,也没限制允许上传的文件类型、没配置上传文件夹,容易被利用进行路径遍历攻击或者上传恶意文件。 - 编码问题未处理:文本文件可能用非UTF-8编码,直接读取会出现解码失败导致程序崩溃的情况。
✅ 修正后的完整代码
import os from flask import Flask, request, jsonify, abort from werkzeug.utils import secure_filename app = Flask(__name__) # 配置上传相关参数 UPLOAD_FOLDER = './uploads' # 只允许上传txt文本文件,避免恶意文件 ALLOWED_EXTENSIONS = {'txt'} app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER # 自动创建上传文件夹(如果不存在) os.makedirs(UPLOAD_FOLDER, exist_ok=True) def allowed_file(filename): """检查文件扩展名是否合法""" return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/index', methods=['GET']) def index(): return '欢迎使用文本文件读取API!' @app.route('/getfile', methods=['POST']) def getfile(): # 检查请求中是否包含文件部分 if 'file' not in request.files: abort(400, description="请求中没有上传文件") file = request.files['file'] # 检查是否选择了文件(文件名不为空) if file.filename == '': abort(400, description="未选择要上传的文件") # 校验文件类型并处理 if file and allowed_file(file.filename): # 对文件名进行安全处理,防止路径遍历攻击 safe_filename = secure_filename(file.filename) # 可选:如果需要把文件保存到本地,取消下面一行注释 # file.save(os.path.join(app.config['UPLOAD_FOLDER'], safe_filename)) # 读取文件内容并解码为UTF-8字符串,处理解码错误 try: file_content = file.read().decode('utf-8') except UnicodeDecodeError: abort(400, description="文件不是有效的UTF-8编码文本文件") # 返回结构化的JSON响应 return jsonify({ 'filename': safe_filename, 'content': file_content }) else: abort(400, description="无效的文件类型,仅支持.txt文本文件") if __name__ == '__main__': # debug模式方便开发调试,生产环境请关闭 app.run(host='0.0.0.0', debug=True)
📝 关键改进点说明
- 安全配置:设置了专门的上传文件夹,限制仅允许
.txt文件上传,用secure_filename处理文件名,避免恶意路径遍历。 - 请求校验:增加了多层校验,包括是否有文件、是否选择了文件、文件类型是否合法,并且返回明确的400错误和描述,方便前端排查问题。
- 正确读取文件:直接使用
FileStorage对象的read()方法读取内容,不用保存到本地也能获取文本,同时处理了编码错误的情况。 - 结构化响应:返回包含文件名和内容的JSON对象,客户端解析起来更清晰规范。
🧪 测试方法
你可以用curl命令或者Postman来测试这个API:
curl -X POST -F "file=@你的文本文件.txt" http://localhost:5000/getfile
内容的提问来源于stack exchange,提问作者Jonreyan
相关产品推荐
相关产品推荐

