net/http.Redirect în Go

Trimite clientul la altă adresă (antetul Location) cu un cod 3xx: 301 mutat definitiv, 302/303 temporar.

Sintaxă
func Redirect(w ResponseWriter, r *Request, url string, code int)

Ce face net/http.Redirect

http.Redirect(w, r, "/noua-adresa", http.StatusSeeOther) setează antetul Location și codul de stare; browserul (sau clientul HTTP din Go) merge automat la noua adresă. Adresa poate fi relativă la calea cererii sau absolută (https://...).

Coduri obișnuite: http.StatusMovedPermanently (301) când pagina s-a mutat definitiv (motoarele de căutare actualizează legătura), http.StatusFound (302) pentru o mutare temporară, http.StatusSeeOther (303) după trimiterea unui formular POST, ca reîncărcarea paginii să nu retrimită formularul.

Parametri

Parametru Descriere
url Adresa nouă (relativă sau absolută).
code Un cod 3xx: 301, 302, 303, 307 sau 308.

Ce returnează

Nimic.

Exemple

Exemplul 1: Adresă veche mutată definitiv

package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/blog-vechi/", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/invata/go/", http.StatusMovedPermanently)
	})
	rec := httptest.NewRecorder()
	mux.ServeHTTP(rec, httptest.NewRequest("GET", "/blog-vechi/articol", nil))
	fmt.Println("Cod:     ", rec.Code)
	fmt.Println("Location:", rec.Header().Get("Location"))
}

Rezultat

Cod:      301
Location: /invata/go/

Exemplul 2: Clientul urmează redirecționarea singur

După trimiterea formularului, serverul răspunde cu 303; http.Client face automat cererea GET către pagina de confirmare.

package main

import (
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"net/url"
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("POST /comanda", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/multumim?nume="+url.QueryEscape(r.FormValue("nume")), http.StatusSeeOther)
	})
	mux.HandleFunc("GET /multumim", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Mulțumim pentru comandă, %s!", r.URL.Query().Get("nume"))
	})
	srv := httptest.NewServer(mux)
	defer srv.Close()

	resp, err := http.PostForm(srv.URL+"/comanda", url.Values{"nume": {"Ana Pop"}})
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	corp, _ := io.ReadAll(resp.Body)
	fmt.Println("Adresa finală:", resp.Request.URL.Path)
	fmt.Println(resp.StatusCode, string(corp))
}

Rezultat

Adresa finală: /multumim
200 Mulțumim pentru comandă, Ana Pop!

Greșeli frecvente

  • Folosești 301 pentru redirecționări temporare. Browserele țin minte 301 și nu mai întreabă serverul; pentru mutări temporare folosește 302 sau 307.
  • Redirecționezi spre o adresă primită de la utilizator (?next=...) fără verificare: oricine poate face linkuri care trimit vizitatorii pe site-uri străine (open redirect). Acceptă doar căi locale.

Comenzi înrudite

  • net/http.Error: Error trimite un răspuns de eroare cu cod și mesaj text; NotFound trimite 404; StatusText dă textul unui cod (404 → Not Found).
  • net/http.Client: Clientul HTTP configurabil (limită de timp, redirecționări, cookie-uri); Do trimite o cerere, Get o cerere GET.
  • net/http.Post: Post trimite date (ex. JSON) cu tipul de conținut dat; PostForm trimite un formular codat ca application/x-www-form-urlencoded.