如何重定向到一个URL

huangapple go评论85阅读模式
英文:

How to redirect to a url

问题

我想在从上一页收集到数据后向客户端展示另一个页面。但是我在服务器端重定向新的URL时遇到了问题。以下是我的逻辑:

  1. 使用POST方法将用户输入提交到服务器;
  2. 服务器运行saveChoice()函数将用户输入保存到数据库中;
  3. 用户输入保存后,服务器向客户端发送一个新的URL;
  4. 当客户端获取到新的URL时,服务器读取数据库并获取保存的数据。

我在第3步卡住了(以下是流程的示例):

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"])
        /* 第3步:让用户打开另一个URL */
    }
}

这是模板:

<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>

请问我如何重定向到一个新页面?

附注:如果我将URL放在按钮上,那么服务器将不会运行saveChoice()函数。

英文:

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(&quot;&quot;).Parse(tpl_ds)
    checkErr(err)
    err = r.ParseForm()
    checkErr(err)
    err = t.Execute(w, sinfo)
    checkErr(err)

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

And here is the template:

&lt;html&gt;
&lt;script&gt;
  $(function () {
    $(&#39;form&#39;).on(&#39;submit&#39;, function (e) {
      e.preventDefault();
      $.ajax({
        type: &#39;post&#39;,
        data: $(&#39;form&#39;).serialize(),
      });
    });
  });
&lt;/script&gt;
&lt;body&gt;
  &lt;form method=&quot;POST&quot;&gt;
    {{range .List}}
        &lt;input type=&quot;checkbox&quot; name=&quot;choices&quot; value=&quot;{{.}}&quot;&gt; &lt;span&gt;{{.}}&lt;/span&gt;&lt;br&gt;
    {{end}}
    &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
  &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;

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()

答案1

得分: 66

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

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

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

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

注意,表单的action属性定义为/postHandler,将你的saveChoice函数运行的端点名称放在那里。

为了避免http: multiple response.WriteHeader calls错误,你可以使用以下代码。

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)
    }
}

否则,服务器会尝试渲染表单和重定向的URL,这将导致多次调用响应写入器。

英文:

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

if r.Method == &quot;POST&quot; {
    saveChoice(r.Form[&quot;choices&quot;])
    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.

&lt;form action=&quot;/postHandler&quot; method=&quot;post&quot;&gt;
   {{range .List}}
    &lt;input type=&quot;checkbox&quot; name=&quot;choices&quot; value=&quot;{{.}}&quot;&gt; &lt;span&gt;{{.}}&lt;/span&gt;&lt;br&gt;
   {{end}}
    &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
&lt;/form&gt;

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 == &quot;GET&quot; {
      sinfo := Stuff{
        List: some_slice
      }

      t, err := template.New(&quot;&quot;).Parse(tpl_ds)
      checkErr(err)
      err = r.ParseForm()
      checkErr(err)
      err = t.Execute(w, sinfo)
      checkErr(err)
    }
 
    if r.Method == &quot;POST&quot; {
        saveChoice(r.Form[&quot;choices&quot;])
        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.

答案2

得分: 3

包 main

导入 (
"net/http"
"html/template"
)

类型数据 struct {
列表字符串
}

功能主要() {
http.HandleFunc("/", 检查)
}

功能检查(w http.ResponseWriter, r * http.Request) {
如果 r.Method == "GET" {
sinfo := 数据{
列表: "这里是文件列表",
}

var tpl_ds = "index.html"

//t, err := template.New("").Parse(tpl_ds)
t := template.Must(template.ParseFiles(tpl_ds))

r.ParseForm()
t.Execute(w, sinfo)

}

如果 r.Method == "POST" {
保存选择(r.Form["choices"])
http.Redirect(w, r, newUrl, http.StatusSeeOther)
}
}

英文:
package main

import (
  &quot;net/http&quot;
  &quot;html/template&quot;
)

type data struct {
  List string
}

func main() {
  http.HandleFunc(&quot;/&quot;, check)
}

func check(w http.ResponseWriter, r * http.Request) {
  if r.Method == &quot;GET&quot; {
    sinfo: = data {
      List: &quot;Here is a list of the files Located with in&quot;,
    }

    var tpl_ds = &quot;index.html&quot;

    //t, err := template.New(&quot;&quot;).Parse(tpl_ds)
    t: = template.Must(template.ParseFiles(tpl_ds))

    r.ParseForm()
    t.Execute(w, sinfo)
  }

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

huangapple
  • 本文由 发表于 2016年3月11日 15:14:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/35934298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定