You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 -X POST http://127.0.0.1:5000/predict -H "Content-Type: application/json" -d '{"text": "测试文本"}'
    
    如果curl请求成功,说明问题出在前端代码;如果curl也返回400,检查后端解析逻辑。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:32:06