简体   繁体   中英

Why does my Flask app redirect one route even though I haven't configured it to?

I'm trying to write a POST route in Flask, but everytime I test the route it redirects with a 301 code the same url but as a GET request. I don't want it to, because I need the POST body.

I don't see why Flask does this however.

What's further confusing is that in the same flask application there is another route that does not redirect.

I have also tried only setting "POST" as an allowed method, but then the route is still redirected, and the response is a 405 method not allowed, which is logical because I have set that GET is not an allowed method. But why does it redirect at all and to itself no less?

Access logs:

<redacted ip> - - [14/Feb/2019:11:32:39 +0000] "POST /service HTTP/1.1" 301 194 "-" "python-requests/2.21.0"
<redacted ip> - - [14/Feb/2019:11:32:43 +0000] "GET /service HTTP/1.1" 200 8 "-" "python-requests/2.21.0"

App code, please note that two routes that respectively do not and do redirect:

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    @app.route('/path/does/not/redirect')
    def notredirected():
        url_for('static', filename='style.css')
        return render_template('template.html')

    @app.route('/service', strict_slashes=True, methods=["GET", "POST"])
    def service():
        return "Arrived!"

    return app

app = create_app()

My expected result would be that it would be that POST /service would return 200 and Arrived! as its output.

EDIT: If I change the route signature to: @app.route('/service', strict_slashes=True, methods=["POST"]) , it still redirects to a GET request and then returns a 405, because there is no GET route for /service.

<redacted> - - [14/Feb/2019:13:05:27 +0000] "POST /service HTTP/1.1" 301 194 "-" "python-requests/2.21.0"
<redacted> - - [14/Feb/2019:13:05:27 +0000] "GET /service HTTP/1.1" 405 178 "-" "python-requests/2.21.0"

Your service route has been configured to handle both GET and POST requests , but your service route doesn't distinguish between incoming GET and POST requests . By default if you don't specify the supported methods on your route, flask will default to supporting a GET request . However, with no check on the incoming request your service route doesn't know how to handle the incoming request, since both GET and POST are supported, so it attempts a redirect in order to process the request . A simple conditional like the following: if flask.request.method == 'POST': can be used to distinguish between the two types of requests. With that being said, maybe you could try out something like the following:

@app.route('/service', methods=['GET', 'POST']) 
def service():
    if request.method == "GET":
        msg = "GET Request from service route"
        return jsonify({"msg":msg})
    else: # Handle POST Request
        # get JSON payload from POST request
        req_data = request.get_json()

        # Handle data as appropriate

        msg = "POST Request from service route handled"
        return jsonify({"msg": msg})

The problem was that the server redirected all non-https requests to the https variant, which I was unaware of. Since this is not problematic behaviour for us, the solution was specifying in the clients to use https.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM