Skip to content
Advertisement

Server-side redirect without calling GET twice

I’m trying to implement what is basically a multi-step form: submit page 1 with a POST request, then have the user be redirected to page 2 of the form. This ends up making two GET requests (one fetch and one document GET, looking at the network requests), which I’m not sure is right. Why does the initial GET request not just get the HTML page that should be rendered (the response to the fetch request is empty)? Should there actually be two requests in the right pattern for this, or is my understanding of how redirects should work not quite right?

Client code:

fetch("/page-1", {
    method: "POST",
    redirect: "follow",
    <...other params here>
}).then(resp => {
    window.location.href = resp.url;
})

Flask server code:

@app.route("/page-1", methods=["GET", "POST"]
def page_1():
    if request.method == "POST":
        # save page 1 data here
        return redirect(url_for("page-2", _scheme="https", _external=True))
    if request.method == "GET":
        return render_template("page-1.html")

@app.route("/page-2", methods=["GET", "POST"]
def page_2():
    if request.method == "POST":
        # save page 2 data here
    if request.method == "GET":
        # **this code path is called twice every time the user navigates page 1->2
        return render_template("page-2.html")

Advertisement

Answer

  1. fetch makes a POST request to /page-1
  2. The server responds saying “You need to get page-2 instead”
  3. fetch follows the redirect and makes a GET request to /page-2
  4. The server responds with the content of page-2.html after passing it through a template engine
  5. fetch ignores everything about the response except the URL
  6. Your JavaScript assigns the URL to location.href
  7. The browser navigates to that URL, making a GET request to get the content to do so

If you want to process the data with fetch then call a method like response.text() and process the response with JavaScript.

If you want to navigate to the resulting page, then use a regular form submission in the first place. The point of fetch is to make HTTP requests without leaving the current page.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement