http.Redirect()
303、307の例をお見せします。
記述内容が異なるのは、http.Redirect()の第4引数のみです。
templateであるindex.gohtmlです。
formのaction属性に「/bar」を指定します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="POST" action="/bar">
<input type="text" name="fname">
<input type="submit">
</form>
</body>
</html>
main.goです。
var tpl *template.Template
func init() {
tpl = template.Must(template.ParseGlob("templates/*"))
}
func main() {
http.HandleFunc("/", foo) // 「/」にアクセスしたら、fooを実行
http.HandleFunc("/bar", bar) // 「/bar」にアクセスしたら、barを実行
http.HandleFunc("/barred", barred) // 「/barred」にアクセスしたら、barredを実行
http.Handle("/favicon.ico", http.NotFoundHandler())
http.ListenAndServe(":8080", nil)
}
func foo(w http.ResponseWriter, req *http.Request) {
fmt.Println("Your request method at foo: ", req.Method)
}
func bar(w http.ResponseWriter, req *http.Request) {
fmt.Println("Your request method at bar: ", req.Method)
// 下記いずれかを使用
http.Redirect(w, req, "/", http.StatusSeeOther) // 303
http.Redirect(w, req, "/", http.StatusTemporaryRedirect) // 307
}
func barred(w http.ResponseWriter, req *http.Request) {
fmt.Println("Your request method at barred: ", req.Method)
err := tpl.ExecuteTemplate(w, "index.gohtml", nil) // templateを指定し実行
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
303の場合、出力結果は下記の通りです。
Your request method at barred: GET Your request method at bar: POST Your request method at foo: GET // POSTからGETへ変更される
307の場合、出力結果は下記の通りです。
Your request method at barred: GET Your request method at bar: POST Your request method at foo: POST // POSTのまま
続いて301の例をお見せします。
301は恒久的な移転ですので、templateは用意せず、
URL入力により「/bar」にアクセスしたら、「/」へリダイレクトさせます。
func main() {
http.HandleFunc("/", foo)
http.HandleFunc("/bar", bar)
http.Handle("/favicon.ico", http.NotFoundHandler())
http.ListenAndServe(":8080", nil)
}
func foo(w http.ResponseWriter, req *http.Request) {
fmt.Println("Your request method at foo: ", req.Method)
}
func bar(w http.ResponseWriter, req *http.Request) {
fmt.Println("Your request method at bar: ", req.Method)
http.Redirect(w, req, "/", http.StatusMovedPermanently)
}
初回実行時の出力結果は次の通りです。
Your request method at bar: GET Your request method at foo: GET
初回実行時のキャッシュがある前提での、2回目以降の出力結果は次の通りです。
Your request method at foo: GET
ブラウザがMoved Permanentlyを記憶しているので、bar関数は実行されません。
WriteHeader()
http.Redirect()は、次のように書き換えることができます。
func bar(w http.ResponseWriter, req *http.Request) {
...
w.Header().Set("Location", "/")
w.WriteHeader(http.StatusMovedPermanently)
}
http.ResponseWriter.WriteHeader()で、エラーのステータスコード書き込みます。
そして事前に移動先である、header情報の「Location」に移動先のURLをセットします。