TypeError: fetch failed w Node.js przez proxy
Wbudowany fetch w Node.js pokazuje ogólny komunikat „fetch failed”, a prawdziwa przyczyna leży w polu cause. Przy proxy dochodzi jeszcze jedna pułapka: fetch domyślnie nie czyta zmiennych proxy.
Zaktualizowano · Redakcja Prokso
- fetch failed to tylko opakowanie: prawdziwa przyczyna jest w err.cause
- Wbudowany fetch czyta HTTP_PROXY tylko z NODE_USE_ENV_PROXY=1 lub --use-env-proxy
- Najprościej przekazać dispatcher z ProxyAgent z undici bezpośrednio do fetch
Co oznacza błąd
Według dokumentacji Node.js globalny fetch jest zbudowany na bibliotece undici. Gdy żądanie nie udaje się na poziomie sieci, undici odrzuca je błędem TypeError: fetch failed, a pierwotny błąd umieszcza w error.cause. Dlatego patrzeć trzeba właśnie tam: console.log(err.cause).
W cause będzie na przykład ECONNREFUSED, ENOTFOUND, timeout połączenia z kodem UND_ERR_CONNECT_TIMEOUT albo odpowiedź proxy. Jeśli proxy nie przyjęło loginu dla adresu HTTPS, undici pisze Proxy response (407) !== 200 when HTTP Tunneling.
Druga pułapka: zmienne HTTP_PROXY i HTTPS_PROXY wbudowany fetch czyta tylko wtedy, gdy włączona jest wbudowana obsługa proxy. Zmienna NODE_USE_ENV_PROXY=1 pojawiła się w Node.js 24.0.0 i 22.21.0, flaga --use-env-proxy – w 24.5.0 i 22.21.0; dokumentacja oznacza tę funkcję jako aktywnie rozwijaną. Bez tego żądanie idzie bezpośrednio, z pominięciem proxy.
Przyczyny
- Proxy nie jest podłączone. Zmienne środowiskowe są ustawione, ale fetch ich nie czyta bez NODE_USE_ENV_PROXY=1 lub --use-env-proxy, więc żądanie wychodzi z Twojego IP.
- Nieprawidłowy host lub port. W cause widać ECONNREFUSED lub ENOTFOUND: błąd w gw.prokso.com albo port spoza 823, 824 i 10000–20000.
- Login lub hasło nie zostały przyjęte. Dla adresów HTTPS w cause przychodzi „Proxy response (407) !== 200 when HTTP Tunneling”. Bramka Prokso odpowiada w tym przypadku „HTTP/1.1 407 NO_USER”.
- Port SOCKS5 dla agenta HTTP. ProxyAgent z adresem http:// na porcie 824 mówi HTTP do portu SOCKS5 i połączenie nie powstaje.
- Strona nie odpowiedziała na czas. Timeout połączenia lub odczytu: proxy albo strona nie zdążyły odpowiedzieć.
Jak to naprawić
- Wypisz przyczynę:
catch (err) { console.log(err.cause) }. Kod w cause podpowie, od którego kroku zacząć. - Podłącz proxy jawnie: zainstaluj pakiet undici i przekaż do fetch
dispatcher: new ProxyAgent('http://LOGIN:HASŁO@gw.prokso.com:823'). Dokumentacja Node.js potwierdza, że globalny fetch przyjmuje dispatcher zgodny z undici. - Aby brać proxy ze zmiennych środowiskowych, użyj
EnvHttpProxyAgentz undici przezsetGlobalDispatcher()albo uruchom Node.js zNODE_USE_ENV_PROXY=1lub--use-env-proxy, jeśli Twoja wersja to obsługuje. - Przy 407 skopiuj login i hasło z panelu klienta jeszcze raz. Jeśli w haśle są znaki specjalne, zakoduj je przez
encodeURIComponent. Składnię loginu i porty zebraliśmy na stronie login, porty i parametry. - Dla agenta HTTP bierz port 823 albo port 10000–20000 dla stałego IP. Inne sposoby podłączenia – w instrukcji Node.js.
- Jeśli w cause jest timeout, zmniejsz liczbę równoległych żądań i zobacz stronę timeout proxy.
Jak sprawdzić, czy działa
Wykonaj fetch na https://prokso.com/ip z tym samym dispatcherem. Jeśli w JSON jest IP i kraj proxy, połączenie działa. Samą linię możesz osobno sprawdzić w sprawdzaniu proxy.
Diagnoza w 2 minuty
Najpierw wklej linię do sprawdzania proxy. Jeśli tam proxy działa, przyczyna leży w programie lub jego ustawieniach. Jeśli nie - sprawdź linię z terminala:
curl -v -x "http://LOGIN:HASŁO@gw.prokso.com:823" https://api.ipify.org
- Wiersz
< HTTP/1.1 407zaraz poCONNECToznacza, że odpowiada proxy. Nazwa po kodzie, na przykładNO_USER, wskazuje przyczynę. - Proxy odpowiedziało na
CONNECTkodem 200, a potem przyszedł inny kod - proxy działa, tę odpowiedź dała strona. - Brak odpowiedzi, tylko przekroczony czas - połączenie nie dotarło do proxy: sprawdź host, port i sieć.
Instrukcje, w których pojawia się ten błąd
Pytania i odpowiedzi (FAQ)
Dlaczego fetch działa, ale IP w odpowiedzi jest moje?
Najpewniej proxy po prostu nie jest podłączone: wbudowany fetch nie czyta HTTP_PROXY bez NODE_USE_ENV_PROXY=1 lub --use-env-proxy. Przekaż dispatcher jawnie.
Czy NODE_USE_ENV_PROXY obsługuje SOCKS5?
Dokumentacja Node.js opisuje dla wbudowanej obsługi tylko adresy proxy HTTP i HTTPS. Dla SOCKS5 użyj osobnego agenta lub biblioteki.
W cause jest błąd certyfikatu. To wina proxy?
Port 823 nie podmienia certyfikatów stron, więc przyczyny szukaj w systemie lub na stronie. Zobacz <a href="/pl/errors/ssl-certificate-errors">błędy certyfikatu SSL</a>.
Jak sprawdzić wersję undici w Node.js?
Według dokumentacji Node.js – przez właściwość process.versions.undici.
Inne błędy proxy
Rezydencjalne $1.59, mobilne $2.50, serwerowe $0.65 za 1 GB
Rejestracja w minutę, dostęp od razu po płatności.