Ce face net/http.Post
http.Post(url, "application/json", corp) trimite o cerere POST cu corpul citit din corp (orice io.Reader: strings.NewReader, bytes.NewReader, un fișier). Al doilea parametru devine antetul Content-Type, ca serverul să știe cum să citească datele.
http.PostForm(url, valori) codează un url.Values ca formular (nume=Ana&oras=Ia%C8%99i) și setează singur tipul. Este ce trimite un formular HTML obișnuit.
Ca la http.Get: folosesc clientul implicit, fără limită de timp; un cod 4xx/5xx nu este err; corpul răspunsului trebuie închis. Pentru alte metode (PUT, DELETE) sau antete proprii folosește http.NewRequest și Client.Do.
Parametri
| Parametru | Descriere |
|---|---|
url |
Adresa la care trimiți. |
contentType |
Tipul datelor: "application/json", "text/plain" etc. |
body / data |
Corpul cererii (io.Reader) sau câmpurile formularului (url.Values). |
Ce returnează
Răspunsul și o eroare, ca la http.Get.
Exemple
Exemplul 1: Trimiterea unui JSON
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
)
type Comanda struct {
Produs string `json:"produs"`
Bucati int `json:"bucati"`
}
func main() {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var c Comanda
if err := json.NewDecoder(r.Body).Decode(&c); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusCreated)
fmt.Fprintf(w, "primit %s: %d x %s", r.Header.Get("Content-Type"), c.Bucati, c.Produs)
}))
defer srv.Close()
date, _ := json.Marshal(Comanda{Produs: "cafea", Bucati: 2})
resp, err := http.Post(srv.URL+"/comenzi", "application/json", bytes.NewReader(date))
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
corp, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status)
fmt.Println(string(corp))
}
Rezultat
201 Created
primit application/json: 2 x cafea
Exemplul 2: Formular cu PostForm
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
)
func main() {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Content-Type: %s\nnume=%s, oras=%s\n",
r.Header.Get("Content-Type"), r.FormValue("nume"), r.FormValue("oras"))
}))
defer srv.Close()
date := url.Values{}
date.Set("nume", "Ana Popescu")
date.Set("oras", "Iași")
resp, err := http.PostForm(srv.URL+"/abonare", date)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
corp, _ := io.ReadAll(resp.Body)
fmt.Print(string(corp))
fmt.Println("Corp trimis:", date.Encode())
}
Rezultat
Content-Type: application/x-www-form-urlencoded
nume=Ana Popescu, oras=Iași
Corp trimis: nume=Ana+Popescu&oras=Ia%C8%99i
Greșeli frecvente
- Trimiți JSON cu tipul
"text/plain"sau fără tip: multe servere refuză cererea sau nu o citesc. - Trimiți formularul cu
http.Postși scrii singur textul fără codare ("nume=Ana Pop&oras=Iași"): spațiile și diacriticele ajung greșit. FoloseștePostFormsauurl.Values.Encode.
Comenzi înrudite
net/http.Get: Trimite o cerere GET (sau HEAD, doar antete) la adresa dată și returnează răspunsul; corpul trebuie închis.net/http.NewRequest: Construiește o cerere HTTP completă (orice metodă, antete, corp) care se trimite apoi cu Client.Do.net/url.Values: Parametrii unui query string sau ai unui formular: Get, Set, Add, Del, Has și Encode (codare sortată după cheie).encoding/json.Marshal: Transformă o valoare Go (structură, map, slice) în JSON compact; etichetele json:”…” aleg numele și regulile câmpurilor.