1. Obtener solicitud
1.1 Método de acceso directo GET usando el paquete net / http
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("http://www.baidu.com")
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
}
1.2 Cliente personalizado
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
client := &http.Client{
}
request, err := http.NewRequest("GET", "http://www.baidu.com", nil)
if err != nil {
fmt.Println(err)
}
resp, err := client.Do(request)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
}
Usar un HTTP
cliente personalizado significa que la solicitud para establecer encabezados, autenticación básica y cookies. En vista del hecho de que hay muy poca diferencia en el código requerido para realizar una solicitud cuando se usa un método de acceso directo y un cliente HTTP personalizado, se recomienda usar un cliente HTTP personalizado a menos que la tarea a completar sea muy simple.
2. Solicitud POST
package main
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
)
func main() {
data := strings.NewReader(`{"some": "json"}`)
resp, err := http.Post("https://httpbin.org/post", "application/json", data)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
}
Resultado de salida:
{
"args": {
},
"data": "{\"some\": \"json\"}",
"files": {
},
"form": {
},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "16",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "Go-http-client/2.0",
"X-Amzn-Trace-Id": "Root=1-60575025-22341e95217463712e18068e"
},
"json": {
"some": "json"
},
"origin": "192.168.0.110",
"url": "https://httpbin.org/post"
}
3. Depurar HTTP
net/http/httputil
También proporciona la capacidad de facilitarle la depuración del HTTP
enfoque de cliente y servidor. El método del paquete DumpRequestOut
y le DumpResponse
permite ver la solicitud y la respuesta.
Puede modificarse al ejemplo anterior, para usar el net/http/httputil
paquete DumpRequestOut
y los DumpResponse
métodos para admitir la función de registro. Estos métodos muestran los encabezados de solicitud y respuesta, así como el cuerpo de respuesta devuelto.
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httputil"
"strings"
)
func main() {
client := &http.Client{
}
data := strings.NewReader(`{"some": "json"}`)
request, err := http.NewRequest("POST", "https://httpbin.org/post", data)
request.Header.Add("Accept", "application/json") // 增加请求报文头
/*
通过使用 Accept 报头, 客户端告诉服务器它想要的是 application/json,而服务器返回数
据时将 Content-Type 报头设置成了application/json。
*/
if err != nil {
fmt.Println(err)
}
debugReq, err := httputil.DumpRequestOut(request, true)
if err != nil {
fmt.Println(err)
}
fmt.Println("debugReq is ", string(debugReq))
resp, err := client.Do(request)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
debugResponse, err := httputil.DumpResponse(resp, true)
if err != nil {
fmt.Println(err)
}
fmt.Println("debugResponse is ", string(debugResponse))
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(body))
}
Resultado de salida:
debugReq is POST /post HTTP/1.1
Host: httpbin.org
User-Agent: Go-http-client/1.1
Content-Length: 16
Accept: application/json
Accept-Encoding: gzip
{
"some": "json"}
debugResponse is HTTP/2.0 200 OK
Content-Length: 441
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Sun, 21 Mar 2021 14:35:01 GMT
Server: gunicorn/19.9.0
4. Tiempo de espera de procesamiento
Utilice el HTTP
cliente predeterminado , no establece la solicitud de tiempo de espera. Esto significa que si el servidor no responde, la solicitud esperará o se bloqueará indefinidamente. Para cualquier solicitud, se recomienda establecer un período de tiempo de espera. Entonces, si la solicitud no se completa dentro del tiempo especificado, se devolverá un error.
client := &http.Client{
Timeout: 1 * time.Second,
}
La configuración anterior requiere que el cliente complete la solicitud en 1 segundo. Pero debido a que la velocidad de respuesta del servidor no es lo suficientemente rápida. Es muy posible que se agote el tiempo de espera de la solicitud. como sigue:
Post https://httpbin.org/post: net/http:
request canceled (Client.Timeout exceeded while awaiting headers)
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x63491b]