wykonywanie niestandardowych żądań
do tej pory nauczyliśmy się tworzyć proste żądania HTTP, ale nie skupialiśmy się zbytnio na dostosowywaniu żądań, takich jak ustawianie niestandardowych nagłówków żądań lub tworzenie PUT
, PATCH
I DELETE
(i inne) żądania HTTP.
http.Struktura żądania
strukturahttp.Request
konfiguruje żądanie do wysłania., Get
,Post
I Inne metody wystawione przez*http.Client
faktycznie konstruują obiekthttp.Request
wewnętrznie, aby wysłać żądanie.
ta struktura ma wiele pól do konfiguracji połączenia TLS, połączenia keep-alive, danych formularza i innych ustawień, ale poniższe pola są minimalną konfiguracją, z którą możemy pracować.
Więcej informacji o znajdziesz tutaj.,
struktura*http.Request
implementuje wiele metod do modyfikacji obiektu request przed jego wysłaniem. Metoda*Request.AddCookie
dodaje plik cookie do obiektu żądania i *Request.SetBasicAuth
ustawia podstawowy nagłówek autoryzacji żądania. Możesz zbadać te metody stąd.
gdy zbudujemy obiekt request, musimy wykonać żądanie z tym obiektem request ręcznie. W tym celu musimy użyć metody *Client.Do
. Ponieważ Go dostarcza http.DefaultClient
, możemy użyć go do złożenia żądania.,
func (c *Client) Do(req *Request) (*Response, error)
In the above example, we are first creating a *url.URL
object from a URL string by using url.Parse
function. Since Request.URL
field should be an object of type *url.URL
, this step is necessary.,
treść żądania przechowywana w polu Request.Body
powinna być obiektem implementującym interfejs io.ReadCloser
(Grupa interfejsów io.Reader
I io.Closer
). Funkcjastrings.NewReader
zwraca obiektio.Reader
Iioutil.NopCloser
dodaje metodęClose()
w obiekcieio.Reader
.
metodaClose
dodana przezNopCloser
funkcja nic nie robi, po prostu zwraca błądnil
., Ciało żądania jest zamknięte dla We/Wy poprzez wywołanie metody Close()
podczas wysyłania żądania. W rzeczywistym przypadku użycia należy poprawnie zaimplementować metodę Close
, aby wyłączyć I/O w treści żądania.
zainicjowaliśmy również poleHeader
z niektórymi początkowymi nagłówkami żądań. Aby wysłać żądanie, używamy metody DefaultClient.Do
, która zwraca odpowiedź sieci i błąd non-nil
, jeśli żądanie się nie powiedzie.,
🌶 go run go-http-client.go
status: 200
body: {"status":"success","data":{"name":"test","salary":"123","age":"23","id":53}}
zgadzam się, wysyłanie niestandardowego żądania wydaje się dość skomplikowane, ale możemy użyć funkcjihttp.NewRequest
do zbudowania obiektu*http.Request
z kilku prostych wartości, które mają następującą składnię.
func NewRequest(method, url string, body io.Reader) (*Request, error)
Ta funkcja zwraca*http.Request
obiekt Inon-nil
błąd, jeśli niektóre wartości argumentów nie są poprawne. Jeśli argument method
jest pusty, przyjmuje się żądanie GET
., We can add headers to the returned *Request
object.
The program above returns the same response as the earlier example., Mimo żereqBody
nie implementujeio.Closer
interfejs, powinien idealnie zaimplementować poprawnąClose
metodę, która wyłącza I/O, w przeciwnym razie Go dodaje metodę Zamknięcia Bez op za pomocąioutil.NopCloser
funkcja.
http.Struktura klienta
strukturahttp.Client
tworzy klienta HTTP z pewną konfiguracją, która może wysyłać żądania HTTP. http.DefaultClient
jest wskaźnikiem do pustego obiektuhttp.Client
, który wyświetla domyślnego klienta HTTP.,
var DefaultClient = &http.Client{}
jak widzieliśmy wcześniej, *http.Client
implementuje Get
, Post
, PostForm
, Head
I Do
metody. Zobaczmy, jak wygląda typ struktury http.Client
.
type Client struct {
// mechanism by which individual HTTP requests are made
Transport RoundTripper
// specifies the policy for handling redirects
CheckRedirect func(req *Request, via *Request) error// specifies the cookie jar
Jar CookieJar
// specifies a time limit for requests
Timeout time.Duration
}
poleTransport
obiekt, który implementuje metodęRoundTrip
. Obiekt ten jest odpowiedzialny za wykonanie pojedynczego żądania HTTP i zwrócenie odpowiedzi., Jeśli wartość tego pola wynosi nil
, to jest używane http.DefaultTransport
typu *http.Transport
. W większości przypadków ta wartość domyślna jest dla nas wystarczająco dobra.
poleCheckRedirect
jest funkcją, która sprawdza, czy należy postępować zgodnie z przekierowaniem wymaganym przez odpowiedź. Jeśli ta wartość to nil
, używana jest domyślna Polityka maksymalnego przekierowania 10
.
argumentreq
jest najnowszym żądaniem, a argumentvia
zawiera starsze żądania (w starej pierwszej kolejności)., Jeśli ta funkcja zwróci błąd non-nil
, próba przekierowania zostanie zablokowana. Sprawdź tę dokumentację, aby dowiedzieć się więcej o sposobie zwracania odpowiedzi i typach błędów.
poleJar
określa mechanizm dodawania plików cookie do wychodzących żądań HTTP i plików cookie pamięci podręcznej z przychodzących odpowiedzi. Ten plik cookie jest konsultowany dla każdego wychodzącego i przekierowanego żądania.
Jeśli ta wartość tonil
, pliki cookie są wysyłane tylko wtedy, gdy zostały określone w żądaniu (i skopiowane do przekierowanych żądań)., W przypadku przekierowania żądania cookie jar może mutować wartości pliku cookie. Możesz użyć pakietu net/http/cookiejar
, aby utworzyć niestandardowy słoik cookie.
poleTimeout
określa limit czasu, przed którym należy odczytać odpowiedź. If wartość pola if 0
co oznacza, że klient HTTP nie ma limitu czasu. Wartość ta wskazuje czas do pełnego odczytania ostatecznej odpowiedzi, która obejmuje wszystkie przekierowania i odczyt odpowiedzi.,
⚠ ️ ponieważ domyślną wartością
Timeout
jest0
, może to być niebezpieczne w niektórych scenariuszach, w których złośliwa usługa nigdy nie wysyła odpowiedzi, wyczerpując przepustowość i powodując inne problemy. Dlatego pamiętaj, aby dodać pewien czas dla każdego żądania, które pochodzi z twojego komputera.
aby sprawdzić, czy błąd zwracany przez*Client.Get
(lub inną metodę) wynika z limitu czasu, powinniśmy sprawdzićerr.Timeout()
wartość., Jeśli timeout wystąpi podczas czytania ciała odpowiedzi, zwróci błąd.
stwórzmy nowego klienta z małą wartością timeout i wyślij proste zapytanie HTTPGET
. Ustawimy wartość timeout 100 milliseconds
I ponieważ istnieje duże prawdopodobieństwo wystąpienia timeoutu żądania, sprawdzimy również błąd timeout.,
In the example above, we have created an HTTP client with a timeout of 100ms
. Since Get
, Post
and other methods are implemented by the pointer of http.Client
type, the client
is a pointer.,
ponieważ błąd zwracany przezGet
metoda (i inne metody) jest zawsze typu*url.Error
, musimy wyodrębnić tę konkretną wartość z err
, który jest typu error
interfejs.
gdy błąd wystąpi z powodu limitu czasu, metoda*Error.Temporary()
zwracatrue
. Z poniższego wyniku widzimy, że błąd zwracany przezGet
jest rzeczywiście spowodowany timeoutem.