2016-10-12 6 views
4

Ich schaffe meine Form wie folgt aus:Senden POST-Anfrage in Golang mit Kopf

form := url.Values{} 
form.Add("region", "San Francisco") 
if len(params) > 0 { 
    for i := 0; i < len(params); i += 2 { 
     form.Add(params[i], params[i+1]) 
    } 
    testLog.Infof("form %v", form) 

Nun, wenn ich

verwenden
resp, err = http.PostForm(address+r.Path, form) 

dann mit einem erwarteten Cookie eine Antwort alles funktioniert gut, ich zurück.

Allerdings würde Ich mag einen Header hinzuzufügen, in dem Fall, dass ich nicht verwenden können PostForm daher habe ich meine POST request manuell wie:

req, err := http.NewRequest("POST", address+r.Path, strings.NewReader(form.Encode())) 

dann die Anfrage ich Sachen an den Header hinzufügen und senden

req.Header.Add("region", "San Francisco") 
resp, err = http.DefaultClient.Do(req) 

Aber das Formular wird nicht empfangen und meine Antwort enthält kein Cookie.

Wenn ich die req drucken, es sieht aus wie die Form nil ist:

&{POST http://localhost:8081/login HTTP/1.1 1 1 map[Region:[San Francisco]] {0xc420553600} 78 [] false localhost:8081 map[] map[] <nil> map[] <nil> <nil> <nil> <nil>} 
+0

Dies ist eine Webseite veröffentlichen das Formular hinzuzufügen ist, nicht wahr? Sie müssen JS dafür verwenden, wenn das der Fall ist. Wenn Sie mit der Vorlage arbeiten, wird bei Go-Code nichts gepostet, sondern lediglich HTML mit einem Eingabeelement vom Typ "Senden" generiert. Diese Anfrage kann jedoch nicht im Browser ausgeführt werden, sie muss auf dem System ausgeführt werden. Wenn Sie also ein HTML-Formular verwenden, das den POST an ein Go-Back-Ende übergibt und Sie Header hinzufügen möchten, müssen Sie eine 'XMLHttpRequest' in JavaScript verwenden, um das zu erreichen. – evanmcdonnal

+0

Nein, keine Webseite, dies ist ein Go Unit Test. Siehe die Antwort unten, die Einstellung des Inhaltstyps in der Kopfzeile hat mein Problem behoben. – Jana

Antwort

10

Sie benötigen einen Inhaltstyp auf Ihre Anfrage hinzuzufügen.

Sie sagte http.PostForm gearbeitet, so schauen wir uns die source davon aussehen:

func PostForm(url string, data url.Values) (resp *Response, err error) { 
    return DefaultClient.PostForm(url, data) 
} 

OK so ist es nur ein Wrapper um die PostForm Methode auf dem Standard-Client. Schauen wir uns an that:

func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) { 
    return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) 
} 

OK den Post Methode ruft und vorbei in "application/x-www-form-urlencoded" für bodyType und die gleiche Sache für den Körper, die Sie tun. Schauen wir uns an the Post method

func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) { 
    req, err := NewRequest("POST", url, body) 
    if err != nil { 
     return nil, err 
    } 
    req.Header.Set("Content-Type", bodyType) 
    return c.doFollowingRedirects(req, shouldRedirectPost) 
} 

So ist die Lösung für Ihr Problem

req.Header.Set("Content-Type", "application/x-www-form-urlencoded")