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

如何修复Flask应用中出现的405 Method Not Allowed报错?

问题修复方案

报错根因

你遇到的报错对应两个核心逻辑问题:

  • GET /predict HTTP/1.1 405:/predict路由仅配置了POST请求权限,你在POST处理完成后直接重定向回/predict地址,重定向默认触发GET请求,直接触发权限拦截。
  • GET /display/ HTTP/1.1 404:首页渲染时没有给模板传递filename参数,img标签生成的请求路径缺少文件名参数,匹配不到路由。

除此之外还有三处隐藏逻辑错误会导致功能无法正常运行:

  • 表单没有配置enctype="multipart/form-data"属性,后端无法接收到上传的文件
  • 调用fcr函数时参数传反,无法正常读取测试图片进行人脸识别
  • 识别结果图片保存时没有加后缀,展示接口无法正常读取文件

分步修改方案

1. 修改app.py

首先添加根uploads目录初始化逻辑,然后修改predict路由的返回逻辑,不要重定向到/predict,直接渲染首页并传递结果图片文件名:

import os
from flask import Flask, flash, request, redirect, render_template, url_for, send_file
import flask
from werkzeug.utils import secure_filename
import fcr_cv
from fcr_cv import fcr

app = Flask(__name__)

app.secret_key = "secret key"
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

# 新增:初始化根uploads目录
ROOT_UPLOAD = os.path.join(os.getcwd(), 'uploads')
os.makedirs(ROOT_UPLOAD, exist_ok=True)

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def validate_input(request: flask.Request):
    input = {}
    try:
        input["sample"] = request.files.getlist('sample')
        input["test"] = request.files.get("test")
        input["folder"] = request.form["folder"]
    except Exception as e:
        print(e)
        return False, input
    return True, input

@app.route('/predict', methods=['POST'])
def predict():
    if request.method == 'POST':
        if 'sample' not in request.files:
            flash('No file part')
            return redirect(url_for('upload_form'))
        if 'test' not in request.files:
            flash('No test part')
            return redirect(url_for('upload_form'))

        is_valid, input = validate_input(request)
        if not is_valid:
            flash('Invalid input')
            return redirect(url_for('upload_form'))

        files = input["sample"]
        folder_name = input["folder"]
        sample_path = os.path.join(ROOT_UPLOAD, folder_name)
        os.makedirs(sample_path, exist_ok=True)
        for file in files:
            if allowed_file(file.filename):
                filename = secure_filename(file.filename)
                file.save(os.path.join(sample_path, filename))

        file = input["test"]
        test_filepath = os.path.join(ROOT_UPLOAD, "test_image.jpg")
        if allowed_file(file.filename):
            file.save(test_filepath)
        # 修正:fcr参数顺序调换,第一个参数是测试图片路径,第二个是样本文件夹路径
        target_image = fcr_cv.fcr(test_filepath, sample_path)
        flash('Image successfully uploaded and displayed below')
        # 修正:渲染首页并传递结果文件名
        return render_template('upload.html', filename=target_image)
    else:
        flash('Allowed image types are -> png, jpg, jpeg, gif')
        return redirect(url_for('upload_form'))

@app.route('/')
def upload_form():
    # 首次加载不传filename,避免生成空的display请求
    return render_template('upload.html', filename=None)

@app.route('/display/<filename>')
def cv_display_image(filename):
    return send_file(os.path.join(ROOT_UPLOAD, filename), mimetype='image/jpeg')

if __name__ == "__main__":
    app.run()

2. 修改upload.html

添加表单文件上传属性,修正标签顺序,添加图片展示判断逻辑:

<html>
<head>
<title>Python Flask Multiple Files Upload Example</title>
</head>
<body>
<h2>Select file(s) to upload</h2>
<!-- 新增enctype属性支持文件上传 -->
<form class="form" action="{{ url_for('predict') }}" method="POST" enctype="multipart/form-data">
    <div class="row">
        <p class="label">Sample files</p>
        <input class="input" type="file" name="sample" multiple="true" autocomplete="off" required>
    </div>
    <div class="row">
        <p class="label">Folder Name</p>
        <input type="text" name="folder" required>
    </div>
    <div class="row">
        <p class="label">Test File</p>
        <input class="input" type="file" name="test" autocomplete="off" required>
    </div>
    <input type="submit" name="submit" value="Predict">
</form>
<!-- 新增判断:只有有结果图片的时候才加载 -->
{% if filename %}
<div>
    <img src="{{ url_for('cv_display_image', filename=filename) }}">
</div>
{% endif %}
</body>
</html>

3. 修改fcr_cv.py

修正结果图片保存逻辑,添加文件后缀:

# 其余代码不变,只修改imwrite和返回值行
cv2.imwrite('./uploads/target_image.jpg', image)
return "target_image.jpg"

内容的提问来源于stack exchange,提问作者Sambam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:45:01