Flask应用POST请求至/predict接口时出现400 BAD REQUEST错误求助
Flask POST请求400 BAD REQUEST错误排查与解决
问题详情
向http://127.0.0.1:5000/predict发送POST请求时触发400 BAD REQUEST错误,页面可正常加载,但请求失败。控制台日志如下:
POST http://127.0.0.1:5000/predict 400 (BAD REQUEST) sendRequest @ script.js:3 onclick @ (index):13
同时前端捕获到错误:
script.js:20 Error: Error: Server error: BAD REQUEST at script.js:12:19
相关代码文件
1. app.py
from flask import Flask, request, jsonify, send_from_directory from flask_cors import CORS import logging from transformers import TFGPT2LMHeadModel, GPT2Tokenizer import os # Configure logging logging.basicConfig(level=logging.DEBUG) # Load the GPT-2 model and tokenizer model_name = "gpt2" model = TFGPT2LMHeadModel.from_pretrained(model_name) tokenizer = GPT2Tokenizer.from_pretrained(model_name) app = Flask(__name__, static_folder='static') CORS(app) @app.route('/') def serve_index(): try: return send_from_directory(app.static_folder, 'index.html') except FileNotFoundError: return jsonify({'error': 'index.html not found'}), 404 @app.route('/predict', methods=['POST']) def predict(): try: data = request.get_json() print(f"Incoming request data: {data}") # Log incoming data for debugging if not data: return jsonify({'error': 'No JSON data provided'}), 400 text = data.get('text') if not text: return jsonify({'error': 'No text provided'}), 400 # Generate a response using GPT-2 with attention mask max_length = 150 # Adjust as needed inputs = tokenizer.encode_plus( text, return_tensors='tf', padding='max_length', # Use padding='max_length' truncation=True, max_length=max_length # Crucial: Set max_length ) input_ids = inputs['input_ids'] attention_mask = inputs['attention_mask'] outputs = model.generate( input_ids, attention_mask=attention_mask, max_length=max_length, num_return_sequences=1, pad_token_id=tokenizer.eos_token_id ) response_text = tokenizer.decode(outputs[0], skip_special_tokens=True) logging.debug(f"Generated response: {response_text}") return jsonify({'response': response_text}) except ValueError as e: logging.error(f"Input Error: {e}") return jsonify({'error': str(e)}), 400 # 400 Bad Request for input errors except Exception as e: logging.error(f"Model Error: {e}") return jsonify({'error': 'An error occurred during prediction'}), 500 if __name__ == '__main__': try: app.run(host='0.0.0.0', port=5000, debug=True) # Set debug=False for production except Exception as e: logging.error(f"Failed to start the Flask server: {e}") raise
2. script.js
function sendRequest() { const textInput = document.getElementById('textInput').value; fetch('/predict', { // Switch to port 5000 method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: textInput }) // This is the JSON sent to Flask }) .then(response => { if (!response.ok) { throw new Error(`Server error: ${response.statusText}`); } return response.json(); }) .then(data => { document.getElementById('response').innerText = `Response: ${data.response}`; }) .catch(error => { console.error('Error:', error); document.getElementById('response').innerText = `Error: ${error}`; }); }
排查与解决步骤
1. 确认请求数据是否正常到达后端
启动Flask服务后,查看控制台的Incoming request data: {data}输出:
- 如果输出是
None,说明前端发送的JSON无法被解析。可以用curl直接测试后端接口:
如果curl请求成功,说明问题出在前端代码;如果curl也返回400,检查后端解析逻辑。curl -X POST http://127.0.0.1:5000/predict -H "Content-Type: application/json" -d '{"text": "测试文本"}'
2. 拦截前端空输入
如果用户未输入内容就点击按钮,后端会返回No text provided的400错误。在前端代码里添加空值判断:
function sendRequest() { const textInput = document.getElementById('textInput').value.trim(); if (!textInput) { document.getElementById('response').innerText = "Error: 请输入文本内容"; return; } // 原有fetch代码保持不变 }
3. 检查原始请求体
在app.py的predict函数中添加原始请求数据打印,确认请求体格式是否正确:
@app.route('/predict', methods=['POST']) def predict(): try: print(f"Raw request data: {request.data}") # 新增打印原始数据 data = request.get_json() print(f"Incoming request data: {data}") # 后续代码不变 # ...
如果request.data不是合法JSON,说明前端发送的格式有误,检查JSON.stringify是否正确。
4. 排查模型处理逻辑
暂时注释掉模型生成代码,返回测试响应,确认是否是模型部分触发的400:
# 替换模型生成相关代码 response_text = "测试响应内容" logging.debug(f"Generated response: {response_text}") return jsonify({'response': response_text})
如果此时请求成功,说明问题出在模型处理环节,查看Flask控制台的Input Error日志,定位具体的ValueError原因(比如tokenizer参数错误、模型加载异常等)。
5. 调整CORS配置(可选)
如果是跨域相关问题,尝试更明确的CORS配置:
CORS(app, resources={r"/predict": {"origins": "*"}})
内容的提问来源于stack exchange,提问作者Teejay
相关产品推荐
相关产品推荐

