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

W skrócie
  • 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ć

  1. Wypisz przyczynę: catch (err) { console.log(err.cause) }. Kod w cause podpowie, od którego kroku zacząć.
  2. 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.
  3. Aby brać proxy ze zmiennych środowiskowych, użyj EnvHttpProxyAgent z undici przez setGlobalDispatcher() albo uruchom Node.js z NODE_USE_ENV_PROXY=1 lub --use-env-proxy, jeśli Twoja wersja to obsługuje.
  4. 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.
  5. Dla agenta HTTP bierz port 823 albo port 10000–20000 dla stałego IP. Inne sposoby podłączenia – w instrukcji Node.js.
  6. 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 407 zaraz po CONNECT oznacza, że odpowiada proxy. Nazwa po kodzie, na przykład NO_USER, wskazuje przyczynę.
  • Proxy odpowiedziało na CONNECT kodem 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.

Rezydencjalne $1.59, mobilne $2.50, serwerowe $0.65 za 1 GB

Rejestracja w minutę, dostęp od razu po płatności.

Utwórz konto