Go 封裝了非常方便的客戶端方法,不再需要藉助第三方包,就可以實現客戶端的請求。本篇文章主要將的是 Get 、 Post 、PostForm 三個基礎的方法。
這個方法非常的簡單,就是從指定的地址獲取到內容,可以簡單的理解成我們用瀏覽器開啟一個頁面。
Get 函式
語法:
Get(url string) (resp *Response, err error)
引數:
- 字串型別的 url 地址,需要注意的是這裡要是完整地址,要加上
http://
或https://
的地址
返回值:
-
*Response 如果獲取到了資料,會將資料儲存在 Response 中
- error 如果請求資料的時候出現錯誤,會返回一個 error ,並將具體的錯誤記錄到 error 中
另外一種方式 Get 方法
可以通過 client 結構體的 Get() 方法獲取資料,其實兩種方式是一樣的,Get() 函式也是呼叫的結構體中的 Get() 方法。詳細的使用可以見示例中的用法
示例:
client.go
package main
import (
"net/http"
"log"
"io/ioutil"
"os"
"fmt"
)
const url = "https://broqiang.com"
func main() {
// 方式一,直接通過 Get 函式
resp, err := http.Get(url)
ErrPrint(err)
defer resp.Body.Close()
// 拿到資料
bytes, err := ioutil.ReadAll(resp.Body)
ErrPrint(err)
// 這裡要格式化再輸出,因為 ReadAll 返回的是位元組切片
fmt.Println("------------- 方法一 ---------------")
fmt.Printf("%s",bytes)
// 方式二,通過 client 結構體的 Get 方法
client := new(http.Client)
// 或
client = &http.Client{}
resp, err = client.Get(url)
ErrPrint(err)
defer resp.Body.Close()
res, err := ioutil.ReadAll(resp.Body)
ErrPrint(err)
fmt.Println("\n\n\n------------- 方法二 ---------------")
fmt.Printf("%s",res)
}
func ErrPrint(err error) {
if err != nil {
log.Fatalln(err)
os.Exit(1)
}
}
這個方法也比較簡單,就是通過 Post 方式和伺服器端互動。
POST 函式
語法:
(url string, contentType string, body io.Reader) (resp *Response, err error)
引數:
-
字串型別的 url 地址,需要注意的是這裡要是完整地址,要加上
http://
或https://
的地址 -
字串型別的 contentType ,Post 提交資料的型別,常見的有下面 4 種:
-
application/x-www-form-urlencoded
不設定 enctype 屬性的原生 form 表單提交方式。 -
multipart/form-data
上傳檔案時的資料提交方式,相當於 form 表單的 enctype 等於 multipart/form-data 。 -
application/json
用來告訴服務端訊息主體是序列化後的 JSON 字串。 text/xml
它是一種使用 HTTP 作為傳輸協議,XML 作為編碼方式的遠端呼叫規範,和 json 作用型別。
-
- 實現了 io.Reader 介面的資料。 如: 可以通過
strings.NewReader()
方法將普通字串實現 io.Reader 介面。
返回值:
-
*Response 如果獲取到了資料,會將資料儲存在 Response 中
- error 如果請求資料的時候出現錯誤,會返回一個 error ,並將具體的錯誤記錄到 error 中
另外一種方式 Post 方法
可以通過 client 結構體的 Post() 方法獲取資料,其實兩種方式是一樣的,Post() 函式也是呼叫的結構體中的 Post() 方法。詳細的使用可以見示例中的用法
示例:
這個示例要和伺服器端互動資料,所以要有一個伺服器端和一個客戶端,伺服器端見目錄中的伺服器端內容(如果你很快就發現了這個文件,可能還沒來得及寫伺服器端)。
伺服器端程式碼
server.go
可以通過 http://localhost:8080/hello 來訪問伺服器端,但是要是 Post 方式才可以。測試的時候注意要先啟動伺服器端,再啟動客戶端。
package main
import (
"net/http"
"fmt"
"log"
)
func main() {
http.HandleFunc("/hello", func(w http.ResponseWriter, req *http.Request) {
if req.Method == "POST" {
fmt.Fprintf(w,"Hello %s\n",req.FormValue("name"))
return
}
http.NotFound(w,req)
})
log.Fatalf("%v",http.ListenAndServe("localhost:8080",nil))
}
客戶端程式碼
client.go
package main
import (
"log"
"os"
"net/http"
"strings"
"fmt"
"io/ioutil"
"io"
)
const url = "http://localhost:8080/hello"
func main() {
// 方式一,直接通過 Post 函式
fmt.Println("------------- 方法一 ---------------")
resp, err := http.Post(url,"application/x-www-form-urlencoded",
strings.NewReader("name=Bro Qiang"))
ErrPrint(err)
defer resp.Body.Close()
DataPrint(resp.Body)
// 方式二,通過 client 結構體中的 Post 方法
fmt.Println("------------- 方法二 ---------------")
client := &http.Client{}
resp, err = client.Post(url,"application/x-www-form-urlencoded",
strings.NewReader("name=New Bro Qiang"))
ErrPrint(err)
defer resp.Body.Close()
DataPrint(resp.Body)
}
func DataPrint(body io.ReadCloser) {
// 拿到資料
bytes, err := ioutil.ReadAll(body)
ErrPrint(err)
// 這裡要格式化再輸出,因為 ReadAll 返回的是位元組切片
fmt.Printf("%s",bytes)
}
func ErrPrint(err error) {
if err != nil {
log.Fatalln(err)
os.Exit(1)
}
}
這個方法是通過 Post 方式向伺服器端提交一個 form 表單,和 html 中的 form 表單提交型別。
PostForm 函式
語法:
PostForm(url string, data url.Values) (resp *Response, err error)
引數:
-
字串型別的 url 地址,需要注意的是這裡要是完整地址,要加上
http://
或https://
的地址 - url.Values 型別的資料, 它的型別實際是一個
map[string][]string
返回值:
-
*Response 如果獲取到了資料,會將資料儲存在 Response 中
- error 如果請求資料的時候出現錯誤,會返回一個 error ,並將具體的錯誤記錄到 error 中
另外一種方式 PostForm 方法
可以通過 client 結構體的 PostForm() 方法獲取資料,其實兩種方式是一樣的,PostForm() 函式也是呼叫的結構體中的 PostForm() 方法。詳細的使用可以見示例中的用法
示例:
建立一個伺服器端,用來接收 from 表單,並將資料在控制檯列印,並給客戶端返回是否成功。
建立一個客戶端,用來向伺服器端傳送 form 表單。
注意: 客戶端的 resp.Body 不要忘記關閉。
伺服器端
server.go
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/form", MyForm)
log.Fatalf("%v",
http.ListenAndServe("localhost:8080", nil))
}
func MyForm(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError),
http.StatusInternalServerError)
return
}
formData := r.Form
log.Printf("收到的資料: %v", formData)
fmt.Fprintf(w, "提交成功")
}
客戶端程式碼
client.go
package main
import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
)
const url = "http://localhost:8080/form"
func main() {
data := map[string][]string{"name": {"Bro Qiang"}, "gender": {"male"}}
// 方法一:PostForm 函式
resp, err := http.PostForm(url, data)
ErrPrint(err)
defer resp.Body.Close()
DataPrint(resp.Body)
// 方法二:client 結構體的 PostForm 方法
client := &http.Client{}
resp, err = client.PostForm(url, data)
ErrPrint(err)
defer resp.Body.Close()
DataPrint(resp.Body)
}
func DataPrint(body io.ReadCloser) {
// 拿到資料
bytes, err := ioutil.ReadAll(body)
ErrPrint(err)
// 這裡要格式化再輸出,因為 ReadAll 返回的是位元組切片
fmt.Printf("%s\n", bytes)
}
func ErrPrint(err error) {
if err != nil {
log.Fatalln(err)
os.Exit(1)
}
}