2012-10-06 40 views
17

我正在嘗試使用Go登錄到網站並存儲cookie以備後用。轉到HTTP發佈和使用Cookies

您可以舉例發表一個表單,存儲cookies以及使用cookies訪問另一個頁面的示例代碼嗎?

我想我可能需要做一個客戶端存儲的cookie,通過研究http://gotour.golang.org/src/pkg/net/http/client.go

package main 

import ("net/http" 
     "log" 
     "net/url" 
     ) 

func Login(user, password string) string { 
     postUrl := "http://www.pge.com/eum/login" 

     // Set up Login 
     values := make(url.Values) 
     values.Set("user", user) 
     values.Set("password", password) 

     // Submit form 
     resp, err := http.PostForm(postUrl, values) 
     if err != nil { 
       log.Fatal(err) 
     } 
     defer resp.Body.Close() 

     // How do I store cookies? 
     return "Hello" 
} 

func ViewBill(url string, cookies) string { 

//What do I put here? 

} 
+1

不幸的是,標準的cookie'Jar' implemntation沒有使它成爲GO1但看起來它計劃在將來增加:https://codereview.appspot.com/5544082/ –

+0

看看使用http: //www.gorillatoolkit.org/pkg/sessions – elithrar

回答

39

轉到1.1介紹cookie罐實現net/http/cookiejar

import (
    "net/http" 
    "net/http/cookiejar" 
) 

cookieJar, _ := cookiejar.New(nil) 

client := &http.Client{ 
    Jar: cookieJar, 
} 
14

首先,您需要實現http.CookieJar接口。然後,您可以將其傳遞給您創建的客戶端,並將其用於與客戶端進行的請求。作爲一個基本的例子:

package main 

import (
    "fmt" 
    "net/http" 
    "net/url" 
    "io/ioutil" 
    "sync" 
) 

type Jar struct { 
    lk  sync.Mutex 
    cookies map[string][]*http.Cookie 
} 

func NewJar() *Jar { 
    jar := new(Jar) 
    jar.cookies = make(map[string][]*http.Cookie) 
    return jar 
} 

// SetCookies handles the receipt of the cookies in a reply for the 
// given URL. It may or may not choose to save the cookies, depending 
// on the jar's policy and implementation. 
func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) { 
    jar.lk.Lock() 
    jar.cookies[u.Host] = cookies 
    jar.lk.Unlock() 
} 

// Cookies returns the cookies to send in a request for the given URL. 
// It is up to the implementation to honor the standard cookie use 
// restrictions such as in RFC 6265. 
func (jar *Jar) Cookies(u *url.URL) []*http.Cookie { 
    return jar.cookies[u.Host] 
} 

func main() { 
    jar := NewJar() 
    client := http.Client{nil, nil, jar} 

    resp, _ := client.PostForm("http://www.somesite.com/login", url.Values{ 
     "email": {"myemail"}, 
     "password": {"mypass"}, 
    }) 
    resp.Body.Close() 

    resp, _ = client.Get("http://www.somesite.com/protected") 

    b, _ := ioutil.ReadAll(resp.Body) 
    resp.Body.Close() 

    fmt.Println(string(b)) 
} 
+0

您應該使用cookie jar的主機名上鍵入的映射。對於一個通用的解決方案,商定爲 –

+0

。這與瀏覽器的工作方式類似,但最終取決於實現細節。 – dskinner

+0

「CookieJar的實現必須安全,以供多個goroutine併發使用。」這不是併發安全的。更不用說這將cookies發送給其他主機。我會冷靜下來。 –

5

在Go的1.5版本中,我們可以使用http.NewRequest使用cookie進行發佈請求。

package main                        
import "fmt" 
import "net/http" 
import "io/ioutil" 
import "strings" 

func main() { 
    // Declare http client 
    client := &http.Client{} 

    // Declare post data 
    PostData := strings.NewReader("useId=5&age=12") 

    // Declare HTTP Method and Url 
    req, err := http.NewRequest("POST", "http://localhost/", PostData) 

    // Set cookie 
    req.Header.Set("Cookie", "name=xxxx; count=x") 
    resp, err := client.Do(req) 
    // Read response 
    data, err := ioutil.ReadAll(resp.Body) 

    // error handle 
    if err != nil { 
     fmt.Printf("error = %s \n", err); 
    } 

    // Print response 
    fmt.Printf("Response = %s", string(data)); 
}   
0

這樣做的另一種方式。適用於Go 1.8。

expiration := time.Now().Add(5 * time.Minute) 
    cookie := http.Cookie{Name: "myCookie", Value: "Hello World", Expires: expiration} 
    http.SetCookie(w, &cookie)