There is no problem at all to access network services based on the HTTP protocol through the net.Dial
or net.DialTimeout
function, because the HTTP protocol is based on the TCP/IP protocol stack. But no problems does not mean easy, if through net.Dial
an HTTP programming function, HTTP status code, packet header processing section and the entity it is quite cumbersome for more details (you can read about the HTTP protocol network protocol in the application layer protocol to Learn more), so the Go language standard library has a built-in net/http package to cover the specific implementation of HTTP client and server. Through the net/http
package, we can write HTTP client and server programs more conveniently and quickly.
First, let's look at HTTP client programming.
http.Client
The net/http package provides the most concise HTTP client implementation, and you can directly use the most common GET
and POST
methods to initiate HTTP requests.
Specifically, we can initiate HTTP requests through the following methods provided by net/http
the Client
classes in the package :
func (c *Client) Do(req *Request) (*Response, error)
func (c *Client) Get(url string) (resp *Response, err error)
func (c *Client) Head(url string) (resp *Response, err error)
func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)
The following briefly introduces the use of these methods.
http.Get
Sample code
To initiate a GET request, just call the http.Get()
method and pass in the request URL. The sample code is as follows:
resp, err := http.Get("https://www.csdn.net/")
if err != nil {
fmt.Printf("发起请求失败:%v", err)
return
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
The above code is used to initiate a request to the CSDN homepage and print its web content to the standard output stream.
Bottom call
In fact http.Get
, when a request is initiated http.Client
, the Get
method on the above default object is called by default :
func Get(url string) (resp *Response, err error) {
return DefaultClient.Get(url)
}
And the DefaultClient
default point is the http.Client
object instance:
var DefaultClient = &Client{}
It is net/http
a property of the disclosed package, when we http
on the call Get
, Post
, PostForm
, Head
when the method, the final corresponding method is invoked on the object.
return value
Back to the http.Get()
method itself, the method returns two values, the first is the response object, and the second is the error
object. If an error occurs during the request process, the error
object is not empty, otherwise, the status code and response can be obtained through the response object Header, response entity and other information. The response object belongs to the class http.Response
. You can check the API documentation or source code to understand the specific information of the type. Generally, we can resp.Body
get the response entity, resp.Header
get the response header, and resp.StatusCode
get the response status code.
After getting the response successfully, remember to call the resp.Body
above Close
method to end the network request to release resources.
http.Post
To send data in POST, it is also very simple, just call the http.Post()
method and pass the following 3 parameters in turn:
- URL of the request target
- Resource type of POST request data (MIMEType)
- Data bitstream (
[]byte
form)
The following sample code demonstrates how to upload a user avatar:
resp, err := http.Post("https://xueyuanjun.com/avatar", "image/jpeg", &imageDataBuf)
if err != nil {
// 处理错误
return
}
if resp.StatusCode != http.StatusOK {
// 处理错误
return
}
// ...
The underlying implementation and return value are the http.Get
same.
http.PostForm
http.PostForm()
The method implements the application/x-www-form-urlencoded
POST form submission in the standard encoding format .
The following sample code simulates HTML login form submission:
resp, err := http.PostForm("https://xueyuanjun.com/login", url.Values{"name":{"学院君"}, "password": {"test-passwd"}})
if err != nil {
// 处理错误
return
}
if resp.StatusCode != http.StatusOK {
// 处理错误
return
}
// ...
Note that POST request parameters need to url.Values
be encoded and encapsulated by methods.
The underlying implementation and return value are the http.Get
same.
http.Head
The HTTP Head request means that only the response header information of the target URL is requested, and the response entity is not returned. We can http.Head()
initiate a Head request through a method, which http.Get()
is the same as the method , just pass in the target URL parameters.
The following sample code is used to request the HTTP response header information of the CSDN homepage :
resp, err := http.Head("https://www.csdn.net/")
if err != nil {
fmt.Println("Request Failed: ", err.Error())
return
}
defer resp.Body.Close()
// 打印头信息
for key, value := range resp.Header {
fmt.Println(key, ":", value)
}
http.Head()
The response entity resp.Body
value returned by the method is empty.
The underlying implementation and return value are the http.Get
same.
(*http.Client).Do
Finally, let's take a look at http.Client
the Do
methods of the class .
In most cases http.Get
, http.Post
and http.PostForm
to meet demand, but if we need to initiate HTTP requests to set up more custom request headers, such as:
- Set a custom
User-Agent
, not the defaultGo http package
; - Pass cookie information;
- HTTP requests initiated by other means, such as
PUT
,PATCH
,DELETE
and the like.
At this point, it can be achieved by http.Client
the Do()
method provided by the class . When using this method, the method in the class is no longer called through the default DefaultClient
object http.Client
, but we need to manually instantiate the Client
object and pass in and add custom request header information The request object to initiate an HTTP request:
// 初始化客户端请求对象
req, err := http.NewRequest("GET", "https://xueyuanjun.com", nil)
if err != nil {
fmt.Printf("请求初始化失败:%v", err)
return
}
// 添加自定义请求头
req.Header.Add("Custom-Header", "Custom-Value")
// ... 其它请求头配置
client := &http.Client{
// ... 设置客户端属性
}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("客户端发起请求失败:%v", err)
return
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
The http.NewRequest
method used to initialize the request object needs to pass in three parameters, the first is the request method, the second is the target URL, and the third is the request entity. Only requests such as POST, PUT, and DELETE need to set the request entity , For HEAD and GET, just pass in nil
.
http.NewRequest
The first value returned by the method is the request object instance req
, which belongs to the class http.Request
. You can call the public methods and attributes on this class to customize the request object, such as request method, URL, request header, etc.
After the setting is complete, you can pass the request object into the client.Do()
method to initiate an HTTP request, and the subsequent operations are the same as the previous four basic methods.
More usage details will be introduced separately in subsequent tutorials, such as how to set up cookies, how to upload and download files, how to handle request/response timeouts, etc. Here is just a brief introduction to the use of these basic HTTP request methods.