2016年3月18日 星期五

Golang的 Cookie 操作

在 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)
  • account
  • password
http://localhost:8080/form/submit 登入後的表單送出的 Request
  • id
  • message
下面的 code 是用來「先登入」然後「傳送表單資料」:
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)
}

換句話說, clientJarnil
nil 自然無法存任何東西囉。

簡單來說。要使用 cookie 的話,只要記得給 client 一個 cookie jar 就可以了……

是說,當初到底是誰想到 cookie jar 這詞的?「餅乾罐」,為什麼不是「餅乾盒」,不是「餅乾包」,不是「餅乾們(cookies)」而是「餅乾罐」呢?


註解

  1. Go 1.1 Release Notes

沒有留言:

張貼留言