且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Golang:如何重定向到一个网址

更新时间:2022-12-09 10:52:19

http状态303是适当的响应。所以重定向请求。

  if r.Method ==POST{
saveChoice(r.Form [choices])
http.Redirect(w,r,newUrl,http.StatusSeeOther)
}

如果你的 newUrl 应该返回一个合适的html页面给浏览器,你不需要使用ajax。使用html表单。

 < form action =/ postHandlermethod =post> 
{{range .List}}
< input type =checkboxname =choicesvalue ={{。}}> &LT;跨度&GT; {{}}&LT; /跨度&GT;&LT峰; br&GT;
{{end}}
< input type =submitvalue =Submit>
< / form>

注意 action 的形式被定义为 / postHandler 。把运行你的 saveChoice 函数的端点的名称放在那里。

所以要避免 http:multiple response.WriteHeader calls error you get get this code。

  func checkcheck(w http .ResponseWriter,r * http.Request){
if r.Method ==GET{
sinfo:= Stuff {
List:some_slice
}

t,err:= template.New()。解析(tpl_ds)
checkErr(err)
err = r.ParseForm()
checkErr(err)
err = t.Execute(w,sinfo)
checkErr(err)
}

if r.Method ==POST{
saveChoice(r.Form [choices])
http.Redirect(w,r,newUrl,http.StatusSeeOther)
}
}

否则,服务器将尝试呈现表单和重定向的url,这将导致对响应编写器进行多次调用。


I would like to show client another page after data has been collected from previous page. But I have trouble redirect the new URL on the server side. Here is my logic:

  1. submit user input with POST action to server;
  2. server run function saveChoice() to save user input into a database;
  3. After user input is saved, server send a new URL to client;
  4. By the time the client GET the new URL, server reads the database and get saved data out

And I am stuck on step 3 (here is an example of the flow):

type Stuff struct{
    List []string
}

func checkcheck(w http.ResponseWriter, r *http.Request) {
    sinfo := Stuff{
        List: some_slice
    }

    t, err := template.New("").Parse(tpl_ds)
    checkErr(err)
    err = r.ParseForm()
    checkErr(err)
    err = t.Execute(w, sinfo)
    checkErr(err)

    if r.Method == "POST" {
        saveChoice(r.Form["choices"])
        /* step 3: make user open another URL */
    }
}

And here is the template:

<html>
<script>
  $(function () {
    $('form').on('submit', function (e) {
      e.preventDefault();
      $.ajax({
        type: 'post',
        data: $('form').serialize(),
      });
    });
  });
</script>
<body>
  <form method="POST">
    {{range .List}}
        <input type="checkbox" name="choices" value="{{.}}"> <span>{{.}}</span><br>
    {{end}}
    <input type="submit" value="Submit">
  </form>
</body>
</html>

May I know how I can redirect to a new page?

p.s. If I put URL on button, then server is not going to run saveChoice()

Thanks!

The http status 303 is the appropriate response here. So redirect the request with it.

if r.Method == "POST" {
    saveChoice(r.Form["choices"])
    http.Redirect(w, r, newUrl, http.StatusSeeOther)
}

And if your newUrl is supposed to return a proper html page to the browser, you don't need to use ajax. Use an html form.

<form action="/postHandler" method="post">
   {{range .List}}
    <input type="checkbox" name="choices" value="{{.}}"> <span>{{.}}</span><br>
   {{end}}
    <input type="submit" value="Submit">
</form>

Notice action of the form is defined as /postHandler. Put the name of the endpoint that runs your saveChoice function there.

So to avoid http: multiple response.WriteHeader calls error you get use this code.

  func checkcheck(w http.ResponseWriter, r *http.Request) {
    if r.Method == "GET" {
      sinfo := Stuff{
        List: some_slice
      }

      t, err := template.New("").Parse(tpl_ds)
      checkErr(err)
      err = r.ParseForm()
      checkErr(err)
      err = t.Execute(w, sinfo)
      checkErr(err)
    }

    if r.Method == "POST" {
        saveChoice(r.Form["choices"])
        http.Redirect(w, r, newUrl, http.StatusSeeOther)
    }
  }

Otherwise, the server attempts to render both the form and the redirected url which will result in mutiple calls to the response writer.