如何重定向到一个URL

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

How to redirect to a url

问题

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

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

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

  1. type Stuff struct{
  2. List []string
  3. }
  4. func checkcheck(w http.ResponseWriter, r *http.Request) {
  5. sinfo := Stuff{
  6. List: some_slice
  7. }
  8. t, err := template.New("").Parse(tpl_ds)
  9. checkErr(err)
  10. err = r.ParseForm()
  11. checkErr(err)
  12. err = t.Execute(w, sinfo)
  13. checkErr(err)
  14. if r.Method == "POST" {
  15. saveChoice(r.Form["choices"])
  16. /* 第3步:让用户打开另一个URL */
  17. }
  18. }

这是模板:

  1. <html>
  2. <script>
  3. $(function () {
  4. $('form').on('submit', function (e) {
  5. e.preventDefault();
  6. $.ajax({
  7. type: 'post',
  8. data: $('form').serialize(),
  9. });
  10. });
  11. });
  12. </script>
  13. <body>
  14. <form method="POST">
  15. {{range .List}}
  16. <input type="checkbox" name="choices" value="{{.}}"> <span>{{.}}</span><br>
  17. {{end}}
  18. <input type="submit" value="Submit">
  19. </form>
  20. </body>
  21. </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):

  1. type Stuff struct{
  2. List []string
  3. }
  4. func checkcheck(w http.ResponseWriter, r *http.Request) {
  5. sinfo := Stuff{
  6. List: some_slice
  7. }
  8. t, err := template.New(&quot;&quot;).Parse(tpl_ds)
  9. checkErr(err)
  10. err = r.ParseForm()
  11. checkErr(err)
  12. err = t.Execute(w, sinfo)
  13. checkErr(err)
  14. if r.Method == &quot;POST&quot; {
  15. saveChoice(r.Form[&quot;choices&quot;])
  16. /* step 3: make user open another URL */
  17. }
  18. }

And here is the template:

  1. &lt;html&gt;
  2. &lt;script&gt;
  3. $(function () {
  4. $(&#39;form&#39;).on(&#39;submit&#39;, function (e) {
  5. e.preventDefault();
  6. $.ajax({
  7. type: &#39;post&#39;,
  8. data: $(&#39;form&#39;).serialize(),
  9. });
  10. });
  11. });
  12. &lt;/script&gt;
  13. &lt;body&gt;
  14. &lt;form method=&quot;POST&quot;&gt;
  15. {{range .List}}
  16. &lt;input type=&quot;checkbox&quot; name=&quot;choices&quot; value=&quot;{{.}}&quot;&gt; &lt;span&gt;{{.}}&lt;/span&gt;&lt;br&gt;
  17. {{end}}
  18. &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
  19. &lt;/form&gt;
  20. &lt;/body&gt;
  21. &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是适当的响应。所以用它来重定向请求。

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

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

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

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

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

  1. func checkcheck(w http.ResponseWriter, r *http.Request) {
  2. if r.Method == "GET" {
  3. sinfo := Stuff{
  4. List: some_slice,
  5. }
  6. t, err := template.New("").Parse(tpl_ds)
  7. checkErr(err)
  8. err = r.ParseForm()
  9. checkErr(err)
  10. err = t.Execute(w, sinfo)
  11. checkErr(err)
  12. }
  13. if r.Method == "POST" {
  14. saveChoice(r.Form["choices"])
  15. http.Redirect(w, r, newUrl, http.StatusSeeOther)
  16. }
  17. }

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

英文:

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

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

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.

  1. &lt;form action=&quot;/postHandler&quot; method=&quot;post&quot;&gt;
  2. {{range .List}}
  3. &lt;input type=&quot;checkbox&quot; name=&quot;choices&quot; value=&quot;{{.}}&quot;&gt; &lt;span&gt;{{.}}&lt;/span&gt;&lt;br&gt;
  4. {{end}}
  5. &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
  6. &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.

  1. func checkcheck(w http.ResponseWriter, r *http.Request) {
  2. if r.Method == &quot;GET&quot; {
  3. sinfo := Stuff{
  4. List: some_slice
  5. }
  6. t, err := template.New(&quot;&quot;).Parse(tpl_ds)
  7. checkErr(err)
  8. err = r.ParseForm()
  9. checkErr(err)
  10. err = t.Execute(w, sinfo)
  11. checkErr(err)
  12. }
  13. if r.Method == &quot;POST&quot; {
  14. saveChoice(r.Form[&quot;choices&quot;])
  15. http.Redirect(w, r, newUrl, http.StatusSeeOther)
  16. }
  17. }

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 := 数据{
列表: "这里是文件列表",
}

  1. var tpl_ds = "index.html"
  2. //t, err := template.New("").Parse(tpl_ds)
  3. t := template.Must(template.ParseFiles(tpl_ds))
  4. r.ParseForm()
  5. t.Execute(w, sinfo)

}

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

英文:
  1. package main
  2. import (
  3. &quot;net/http&quot;
  4. &quot;html/template&quot;
  5. )
  6. type data struct {
  7. List string
  8. }
  9. func main() {
  10. http.HandleFunc(&quot;/&quot;, check)
  11. }
  12. func check(w http.ResponseWriter, r * http.Request) {
  13. if r.Method == &quot;GET&quot; {
  14. sinfo: = data {
  15. List: &quot;Here is a list of the files Located with in&quot;,
  16. }
  17. var tpl_ds = &quot;index.html&quot;
  18. //t, err := template.New(&quot;&quot;).Parse(tpl_ds)
  19. t: = template.Must(template.ParseFiles(tpl_ds))
  20. r.ParseForm()
  21. t.Execute(w, sinfo)
  22. }
  23. if r.Method == &quot;POST&quot; {
  24. saveChoice(r.Form[&quot;choices&quot;])
  25. http.Redirect(w, r, newUrl, http.StatusSeeOther)
  26. }
  27. }

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:

确定