首页 > 解决方案 > 服务器端重定向,无需调用 GET 两次

问题描述

我正在尝试实现基本上是一个多步骤表单:使用 POST 请求提交第 1 页,然后将用户重定向到表单的第 2 页。这最终会发出两个 GET 请求(一个fetch和一个documentGET,查看网络请求),我不确定这是否正确。为什么初始 GET 请求不只是获取应该呈现的 HTML 页面(对fetch请求的响应为空)?实际上是否应该有两个正确模式的请求,或者我对重定向应该如何工作的理解不太正确?

客户端代码:

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

烧瓶服务器代码:

@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")

标签: javascriptredirectfetch

解决方案


  1. fetch发出 POST 请求/page-1
  2. 服务器回应说“你需要得到page-2代替”
  3. fetch跟随重定向并发出 GET 请求/page-2
  4. 服务器page-2.html通过模板引擎传递内容后响应
  5. fetch忽略关于响应的所有内容,除了 URL
  6. 您的 JavaScript 将 URL 分配给location.href
  7. 浏览器导航到该 URL,发出 GET 请求以获取内容

如果要处理数据,fetch请调用类似的方法response.text()并使用 JavaScript 处理响应。

如果您想导航到结果页面,请首先使用常规表单提交。要点是在离开当前页面的情况下fetch发出 HTTP 请求。


推荐阅读