package main import ( "fmt" "io/ioutil" "net/http" "os" ) func main() { for _, url := range os.Args[1:] { resp, err := http.Get(url) if err != nil { fmt.Fprintf(os.Stderr, "fetch: %v\n", err) os.Exit(1) } b, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err) os.Exit(1) } fmt.Printf("%s", b) } }
執行命令:
go run main.go http://gopl.io
這個程序從兩個package中導入了函數,net/http和io/ioutil包,http.Get函數是創建HTTP請求
的函數,如果獲取過程沒有出錯,那么會在resp這個結構體中得到訪問的請求結果。resp的
Body字段包括一個可讀的服務器響應流。ioutil.ReadAll函數從response中讀取到全部內容;
將其結果保存在變量b中。resp.Body.Close關閉resp的Body流,防止資源泄露,Printf函數會
將結果b寫出到標准輸出流中。
package main import ( "fmt" "io" "net/http" "os" ) func main() { for _, url := range os.Args[1:] { resp, err := http.Get(url) if err != nil { fmt.Fprintf(os.Stderr, "fetch: %v\n", err) os.Exit(1) } //b, err := ioutil.ReadAll(resp.Body) io.Copy(os.Stdout, resp.Body) resp.Body.Close() if err != nil { fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err) os.Exit(1) } //fmt.Printf("%s", data) } }
函數調用io.Copy(dst, src)會從src中讀取內容,並將讀到的結果寫入到dst中,使用
這個函數替代掉例子中的ioutil.ReadAll來拷貝響應結構體到os.Stdout,避免申請一個緩沖區
(例子中的b)來存儲。記得處理io.Copy返回結果中的錯誤。
如果輸入的url參數沒有 http:// 前綴的話,為這個url加上該
前綴。用到strings.HasPrefix這個函數。
package main import ( "fmt" "io" "net/http" "os" "strings" ) func main() { for _, url := range os.Args[1:] { if strings.HasPrefix(url, "http://") == false { url = "http://" + url } resp, err := http.Get(url) if err != nil { fmt.Fprintf(os.Stderr, "fetch: %v\n", err) os.Exit(1) } //b, err := ioutil.ReadAll(resp.Body) io.Copy(os.Stdout, resp.Body) resp.Body.Close() if err != nil { fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err) os.Exit(1) } //fmt.Printf("%s", data) } }
打印出HTTP協議的狀態碼,可以從resp.Status變量得到該狀態碼。
package main import ( "fmt" "net/http" "os" "strings" ) func main() { for _, url := range os.Args[1:] { if strings.HasPrefix(url, "http://") == false { url = "http://" + url } resp, err := http.Get(url) if err != nil { fmt.Fprintf(os.Stderr, "fetch: %v\n", err) os.Exit(1) } status := resp.Status fmt.Printf("%s", status) if err != nil { fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err) os.Exit(1) } } }