部署Flask Web应用时遭遇Internal Server Error (500)问题求助
Flask部署至Vercel/PythonAnywhere均返回500内部服务器错误排查方案
问题背景
将Flask Web应用部署至Vercel与PythonAnywhere平台时,本地运行正常,但点击提交按钮调用handleSubmit()发起文件处理请求时,云端始终返回Internal Server Error (500),切换平台后问题未解决,仅能看到控制台的500错误提示,无更多排查线索。
相关代码片段
Flask后端代码
from flask import Flask, request, jsonify, Response, send_from_directory, render_template from flask_cors import CORS import pandas as pd import io, os, time app = Flask(__name__, static_folder='static', template_folder='templates') CORS(app) @app.route('/') def index(): return render_template('index.html') @app.route('/process', methods=['POST']) def process_file(): try: type_id = int(request.form.get('buttonID')) uploaded_file = request.files['file'] input_filename = uploaded_file.filename uploaded_file.save(input_filename) output_filename = process_file(input_filename) # 注意:此处存在递归调用问题 file_extension = os.path.splitext(output_filename)[1].lower() if file_extension == '.csv': mimetype = 'text/csv' elif file_extension in ['.xls', '.xlsx']: mimetype = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' else: return jsonify({"error": "Unsupported output file format"}), 400 with open(output_filename, 'rb') as f: file_contents = f.read() return Response( file_contents, mimetype=mimetype, headers={"Content-Disposition": f"attachment;filename={output_filename}"} ) except Exception as e: return jsonify({"error": str(e)}), 500 @app.route('/static/<path:path>') def send_static(path): return send_from_directory('static', path)
注:自定义的文件处理函数也命名为process_file,与路由函数同名
前端JavaScript代码
async function handleSubmit() { if (!selectedButton) { document.getElementById('process-warning').style.display = 'block'; return; } if (!fileForProcessing) { console.error("No file selected."); return; } const formData = new FormData(); formData.append('file', fileForProcessing); formData.append('buttonID', selectedButton); try { const response = await fetch(`${window.location.origin}/process`, { method: 'POST', body: formData }); if (response.status === 200) { newFileData = await response.arrayBuffer(); recvdFile = true; } } catch (error) { console.error(`Error: ${error}`); } finally { document.getElementById('spinner').style.display = 'none'; document.getElementById('processing-incomplete').style.display = 'none'; } }
排查与解决步骤
- 优先获取详细错误日志
- PythonAnywhere:进入控制台的「Web」标签,查看「Error log」中的具体报错信息;Vercel则在项目的「Functions」模块下查看函数执行日志,500错误的具体原因一定会记录在日志中。
- 修复递归调用bug
- 路由函数
process_file与自定义文件处理函数同名,导致调用process_file(input_filename)时触发递归,直接引发栈溢出错误。将自定义处理函数重命名(比如process_uploaded_file),修改调用代码:output_filename = process_uploaded_file(input_filename)
- 路由函数
- 修正文件读写路径权限
- 云端平台的当前工作目录通常无写入权限,不能直接保存文件到当前路径。改用平台允许的临时目录(比如
/tmp/,Vercel和PythonAnywhere均支持):import tempfile # 保存上传文件到临时目录 temp_dir = tempfile.gettempdir() input_filename = os.path.join(temp_dir, uploaded_file.filename) uploaded_file.save(input_filename) # 处理后的输出文件也保存到临时目录 output_filename = os.path.join(temp_dir, process_uploaded_file(input_filename))
- 云端平台的当前工作目录通常无写入权限,不能直接保存文件到当前路径。改用平台允许的临时目录(比如
- 确认依赖与文件完整性
- 检查
requirements.txt是否包含所有依赖包(如flask、flask-cors、pandas、openpyxl等),确保云端环境已安装所有依赖;同时确认模板文件、静态资源、处理函数依赖的本地文件均已上传至云端,路径配置正确。
- 检查
- 完善前端错误处理
- Fetch API仅在网络错误时触发catch,HTTP 500错误不会进入catch块,需添加非200状态的处理逻辑,获取后端返回的错误信息:
try { const response = await fetch(`${window.location.origin}/process`, { method: 'POST', body: formData }); if (response.status === 200) { newFileData = await response.arrayBuffer(); recvdFile = true; } else { const errorData = await response.json(); console.error('服务器错误详情:', errorData.error); } } catch (error) { console.error(`网络错误: ${error}`); }
- Fetch API仅在网络错误时触发catch,HTTP 500错误不会进入catch块,需添加非200状态的处理逻辑,获取后端返回的错误信息:
内容的提问来源于stack exchange,提问作者Shell1500
相关产品推荐
相关产品推荐

