在 GoLang 出 1.1 版以前,Go lang 雖然已經有定義 type CookieJar interface 了,但是只有 interface,那時候要使用 cookie 還要自己定義 [1]。
當時雖然有人有開源自己寫的 cookie jar,不過在 1.1 出來後也不會用到,現在我要找也找不到了……
回到正題。下面 code 是利用 GoLang 連上登入網站(http://localhost:8080),然後傳送資料到表單中。
Requests 如下:
| Request URL | 用途 | 欄位 |
|---|---|---|
| http://localhost:8080 | 網站首頁 | |
| http://localhost:8080/auth | 登入(必須是 POST Request) |
|
| http://localhost:8080/form/submit | 登入後的表單送出的 Request |
|
package main
import (
"io/ioutil"
"log"
"net"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
)
func main() {
defer log.Println("Finish Connection")
defer log.Println("")
log.SetFlags(log.Lshortfile | log.LstdFlags)
connecting_url := "http://localhost:8080/"
jar, err := cookiejar.New(nil)
if err != nil {
log.Fatal(err)
return
}
client := &http.Client{Jar: jar}
res, err := client.PostForm(connecting_url+"/auth?", url.Values{
"account": []string{"admin"},
"password": []string{"123456789"},
})
if err != nil {
log.Fatal(err)
return
}
log.Println("Login Success")
res, err = client.PostForm(connecting_url+"/form/submit", url.Values{
"id": []string{"1"},
"message": []string{"Test connection by Golang!"},
})
robots, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
return
}
log.Printf("%s", robots)
}
這一段 code 最重要的,就是 client := &http.Client{Jar: jar}
如果你是以 http.PostForm(connecting_url+"/auth", ...) 這樣子登入的話,是不會儲存 cookie 的。
如果你有看原始碼的話,http.PostForm 相當於:
package main
import (
"net/http"
)
func main() {
var DefaultClient = &http.Client{}
DefaultClient.PostForm(url, data)
}
換句話說, client 的 Jar 是 nil。
nil 自然無法存任何東西囉。
簡單來說。要使用 cookie 的話,只要記得給 client 一個 cookie jar 就可以了……
是說,當初到底是誰想到 cookie jar 這詞的?「餅乾罐」,為什麼不是「餅乾盒」,不是「餅乾包」,不是「餅乾們(cookies)」而是「餅乾罐」呢?
沒有留言:
張貼留言