<p dir="auto">When trying to redirect from a POST request to another page it seems that the request goes wrong. The redirect seems fine in the browser network debug tab and seems to pass normally from the POST method handling but when it tries to go to the new url it gets a status code of <strong>|405 Method Not Allowed|</strong>. The reason for this it seems by looking at the log is that the request gets mashed up with the query parameter somehow which seems like a bug:</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/19205853/165802744-4480c401-d772-47b8-802b-1aa7431cefa4.png"><img src="https://user-images.githubusercontent.com/19205853/165802744-4480c401-d772-47b8-802b-1aa7431cefa4.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto">Also it seems to work normally if there is no inputs in the form (but that is of no matter as there are no real life forms without any input).</p>
<p dir="auto">Replication steps:</p>
<p dir="auto">Happens on Edge, Chrome and Firefox for sure.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from flask import Flask, request, redirect

app: Flask = Flask(__name__)

@app.route(&quot;/&quot;, methods=[&quot;GET&quot;])
def hello():
    return &quot;&lt;a href='/my_form'&gt;to form&lt;/a&gt;&quot;

@app.route(&quot;/my_form&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
def my_form():
    if request.method == &quot;GET&quot;:
        return &quot;&lt;form action='/my_form' method='POST' &gt;&lt;input type='hidden' name='id' value='0'&gt;&lt;button type='submit'&gt;Submit&lt;/button&gt;&lt;/form&gt;&quot;
    else:
        return redirect(&quot;/&quot;)

# app.run(host=&quot;127.0.0.1&quot;, port=80, debug=True)"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">flask</span> <span class="pl-k">import</span> <span class="pl-v">Flask</span>, <span class="pl-s1">request</span>, <span class="pl-s1">redirect</span>

<span class="pl-s1">app</span>: <span class="pl-v">Flask</span> <span class="pl-c1">=</span> <span class="pl-v">Flask</span>(<span class="pl-s1">__name__</span>)

<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">route</span>(<span class="pl-s">"/"</span>, <span class="pl-s1">methods</span><span class="pl-c1">=</span>[<span class="pl-s">"GET"</span>])</span>
<span class="pl-k">def</span> <span class="pl-en">hello</span>():
    <span class="pl-k">return</span> <span class="pl-s">"&lt;a href='/my_form'&gt;to form&lt;/a&gt;"</span>

<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">route</span>(<span class="pl-s">"/my_form"</span>, <span class="pl-s1">methods</span><span class="pl-c1">=</span>[<span class="pl-s">"GET"</span>, <span class="pl-s">"POST"</span>])</span>
<span class="pl-k">def</span> <span class="pl-en">my_form</span>():
    <span class="pl-k">if</span> <span class="pl-s1">request</span>.<span class="pl-s1">method</span> <span class="pl-c1">==</span> <span class="pl-s">"GET"</span>:
        <span class="pl-k">return</span> <span class="pl-s">"&lt;form action='/my_form' method='POST' &gt;&lt;input type='hidden' name='id' value='0'&gt;&lt;button type='submit'&gt;Submit&lt;/button&gt;&lt;/form&gt;"</span>
    <span class="pl-k">else</span>:
        <span class="pl-k">return</span> <span class="pl-en">redirect</span>(<span class="pl-s">"/"</span>)

<span class="pl-c"># app.run(host="127.0.0.1", port=80, debug=True)</span></pre></div>
<p dir="auto">I would expect that the submission of a form allows for a redirect to the home page without any errors like 405. I don't expect any of the arguments to be passed to the redirected request.</p>
<p dir="auto">Environment:</p>
<ul dir="auto">
<li>Python version: 3.9</li>
<li>Flask version: 2.1.1</li>
</ul>
<p dir="auto">With the following example:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from flask import Flask

app = Flask(__name__)


@app.route('/', methods=['POST'])
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">flask</span> <span class="pl-k">import</span> <span class="pl-v">Flask</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">Flask</span>(<span class="pl-s1">__name__</span>)


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">route</span>(<span class="pl-s">'/'</span>, <span class="pl-s1">methods</span><span class="pl-c1">=</span>[<span class="pl-s">'POST'</span>])</span>
<span class="pl-k">def</span> <span class="pl-en">hello_world</span>():
    <span class="pl-k">return</span> <span class="pl-s">'Hello World!'</span>


<span class="pl-k">if</span> <span class="pl-s1">__name__</span> <span class="pl-c1">==</span> <span class="pl-s">'__main__'</span>:
    <span class="pl-s1">app</span>.<span class="pl-en">run</span>()</pre></div>
<p dir="auto">When you set the request body to <code class="notranslate">{}</code> with Postman or any HTTP clients, the first request will return 200, while the second request will return a 405 error response. The log shows the request method is <code class="notranslate">{}POST</code>:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&quot;{}POST / HTTP/1.1&quot; 405"><pre class="notranslate"><code class="notranslate">"{}POST / HTTP/1.1" 405
</code></pre></div>
<p dir="auto">Notice the request body became the part of the request method.</p>