Как перенаправить на 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"])
        /* step 3: make user open another 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>

Могу ли я узнать, как я могу перенаправить на новую страницу?

ps Если я добавлю URL на кнопку, то сервер не будет запускать saveChoice()

Ответ 1

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-адрес, что приведет к нескольким вызовам автоответчика.

Ответ 2

package main

import (
  "net/http"
  "html/template"
)

type data struct {
  List string
}

func main() {
  http.HandleFunc("/", check)
}

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

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

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