# Konfiguracja proxy w Node.js: Axios, Fetch, Undici i rotacja

Opcja proxy w axios to pułapka dla celów HTTPS, a natywny fetch całkowicie ignoruje zmienne środowiskowe proxy. Oto konfiguracja, która działa w axios, fetch i undici — agenci, autoryzacja, SOCKS5, rotacja i streaming.

Przekierowanie żądań Node.js przez proxy wydaje się być jednowierszowe, a zamienia się w popołudnie debugowania. Powodem jest to, że trzy klienci HTTP, których używa większość projektów — axios, natywny `fetch`, który pojawił się jako globalny w Node 18, i biblioteka undici — każdy z nich przyjmuje proxy inaczej i żaden nie zachowuje się tak, jak się spodziewasz. Axios ma wbudowaną konfigurację `proxy`, która jest udokumentowana, działa tylko w Node i cicho nie działa dla celów HTTPS za HTTP proxy: błąd, który jest otwarty na trackerze GitHub axios od 2020 roku i spowodował mocno głosowany wątek na Stack Overflow. Tymczasem natywny fetch ignoruje zmienne środowiskowe `HTTP_PROXY` i nie ma w ogóle opcji proxy. Ten przewodnik przedstawia konfigurację, która faktycznie działa w każdym kliencie, plus autoryzację, SOCKS5, rotację i streaming.

## Konfiguracja proxy w Axios vs agenci proxy

Axios dostarcza obiekt `proxy` — `{ host, port, auth }` — i działa dobrze dla celów HTTP. Pułapka to HTTPS: gdy celem jest `https://`, a proxy mówi HTTP, axios nie otwiera tunelu CONNECT i twoje żądanie albo zawiesza się, albo wraca z twoim prawdziwym IP. Rozwiązaniem, na które społeczność się zdecydowała, jest całkowite pominięcie wbudowanej konfiguracji i przekazanie axios agentowi proxy, a następnie ustawienie `proxy: false`, aby te dwa mechanizmy się nie kłóciły:

```js
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

// Note the destructured import — a default import is the classic gotcha.
const agent = new HttpsProxyAgent("http://USER:PASS@residentialpremium.quantumproxies.io:8080");

const client = axios.create({
  httpAgent: agent,   // for http:// targets
  httpsAgent: agent,  // for https:// targets
  proxy: false,       // disable axios' own broken proxy handling
  timeout: 15000,
});

const r = await client.get("https://httpbin.org/ip");
console.log(r.data); // { origin: "<proxy exit IP>" }
```

Dwa szczegóły oszczędzają godziny. Po pierwsze, użyj **zdestrukturyzowanego** importu `{ HttpsProxyAgent }` — w nowszych wersjach eksportowany jest jako symbol nazwany, a domyślny import daje obiekt, który rzuca wyjątek podczas konstrukcji. Po drugie, schemat URL proxy pozostaje `http://`, nawet gdy proxy przenosi ruch HTTPS: schemat opisuje, jak dotrzeć do proxy, a TLS do celu działa wewnątrz tunelu. Ten sam rodzaj błędu pojawia się w Pythonie; jeśli również pracujesz w requests, wzorce rymują się z naszym [przewodnikiem naprawy ProxyError i SSLError](https://quantumproxies.io/blog/python-requests-proxyerror-fix).

## Autoryzacja i zmienne środowiskowe

Autoryzowane proxy używają poświadczeń HTTP Basic. Z agentem, osadź je w URL jako `http://user:pass@host:port`; jeśli hasło zawiera `@`, `:` lub `/`, zakoduj je w URL za pomocą `encodeURIComponent()` najpierw, inaczej URL zostanie podzielony w złym miejscu. `407 Proxy Authentication Required` oznacza, że poświadczenia zostały odrzucone lub twoje źródłowe IP nie jest na białej liście. Axios również czyta `HTTP_PROXY`, `HTTPS_PROXY` i `NO_PROXY` ze środowiska — przydatne do proxyzowania biblioteki zewnętrznej bez dotykania jej kodu — i wyłączasz to, ustawiając `proxy: false`. Ważne ostrzeżenie: natywny `fetch` **nie** czyta tych zmiennych, więc scraper, który polega na proxyzowaniu przez zmienne środowiskowe, idzie bezpośrednio w momencie, gdy przełączasz się z axios na fetch.

![Trzy fragmenty kodu dla tego samego żądania: axios przyjmuje HttpsProxyAgent w httpAgent i httpsAgent z proxy: false, natywny fetch przyjmuje dispatcher undici przy każdym wywołaniu, a setGlobalDispatcher z ProxyAgent w undici kieruje przez proxy cały proces. Mylenie ich to najczęstsza przyczyna problemu „proxy nie działa”.](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335145/blog/generated/qp-b9-007-diag1.png)
*To samo żądanie, trzy systemy hydrauliczne. Axios chce agenta, natywny fetch chce dyspozytora undici, a ich mieszanie to główna przyczyna 'proxy nie działa'.*

## Proxyzowanie natywnego fetch za pomocą undici

Globalny `fetch` w Node jest zbudowany na undici, a undici to miejsce, gdzie żyje proxy. Tworzysz `ProxyAgent` i przekazujesz go jako niestandardową opcję `dispatcher` — to nowoczesny, lekki sposób na proxyzowanie fetch, i obsługuje HTTPS CONNECT poprawnie od razu po wyjęciu z pudełka:

```js
import { ProxyAgent } from "undici";

const dispatcher = new ProxyAgent({
  uri: "http://residentialpremium.quantumproxies.io:8080",
  token: "Basic " + Buffer.from("USER:PASS").toString("base64"),
});

const res = await fetch("https://httpbin.org/ip", { dispatcher });
console.log(await res.json());
```

Jeśli używasz undici bezpośrednio zamiast globalnego fetch, ten sam `ProxyAgent` podłącza się do `request()` lub do `setGlobalDispatcher()`, aby proxyzować każdy fetch w procesie naraz. To globalne przełączanie jednym wywołaniem to najczystszy sposób na przekierowanie całej bazy kodu przez proxy bez przekazywania dyspozytora przez każdą funkcję.

## SOCKS5 proxy w Node.js

Ani axios, ani undici nie obsługują SOCKS natywnie — przekazanie ciągu `socks5://` do konfiguracji `proxy` w axios skutkuje asercją `protocol mismatch`. Zainstaluj `socks-proxy-agent` i użyj go w ten sam sposób, co agenta HTTPS, podłączając do `httpAgent` i `httpsAgent`. Preferuj `socks5h://` nad `socks5://`: końcowe `h` rozwiązuje DNS po stronie proxy, co zapobiega wyciekom DNS i rozwiązuje nazwy hostów z ograniczeniami geograficznymi z lokalizacji wyjściowej. Każdy plan [proxy SOCKS5](https://quantumproxies.io/socks5-proxies) udostępnia to samo bramę przez HTTP i SOCKS5, więc to tylko zmiana schematu, a nie nowy zakup:

```js
import axios from "axios";
import { SocksProxyAgent } from "socks-proxy-agent";

const agent = new SocksProxyAgent("socks5h://USER:PASS@residentialpremium.quantumproxies.io:1080");

const client = axios.create({ httpAgent: agent, httpsAgent: agent });
const r = await client.get("https://httpbin.org/ip");
console.log(r.data);
```

## Rotacja bez listy proxy

Stara receptura — tablica IP, `Math.random()` na żądanie, usuwanie martwych — to kod, którego już nie utrzymujesz. Rotacyjna brama przypisuje świeże IP wyjściowe po stronie serwera przy każdym żądaniu, więc jeden punkt końcowy zachowuje się jak cała pula. Poprzez [rotacyjne proxy rezydencjalne](https://quantumproxies.io/rotating-proxies) ta pula obejmuje ponad 90 milionów IP w ponad 200 krajach, a poniższa pętla drukuje różne pochodzenie przy każdej iteracji bez logiki rotacji:

```js
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";

const agent = new HttpsProxyAgent("http://USER:PASS@residentialpremium.quantumproxies.io:8080");
const client = axios.create({ httpAgent: agent, httpsAgent: agent, proxy: false });

for (let i = 0; i < 3; i++) {
  const r = await client.get("https://httpbin.org/ip");
  console.log(r.data.origin); // a different exit IP each time
}
```

Gdy przepływ obejmuje kilka żądań — logowanie, dodanie do koszyka, realizacja zamówienia — rotacja na żądanie przerywa sesję. Parametr sesji lepkiej w nazwie użytkownika proxy przypina jedno IP wyjściowe na określony czas, a następnie rotuje; ten sam punkt końcowy, jedna zmiana ciągu. Jeśli skalujesz to do tysięcy równoczesnych żądań, przenieś pracę poza pętle axios i przeczytaj nasz przewodnik po [architekturze skrobania na dużą skalę](https://quantumproxies.io/blog/large-scale-web-scraping-architecture) dla kolejkowania i budżetów współbieżności.

## Streaming odpowiedzi przez proxy

Pobieranie plików lub dużych ładunków JSON działa tak samo jak każde żądanie po podłączeniu agenta — ustaw `responseType: "stream"` i przekieruj ciało na dysk. Proxy obsługuje transfer przejrzyście, więc eksport 200MB nigdy nie buforuje się w pamięci:

```js
import fs from "node:fs";

const r = await client.get("https://example.com/large.json", {
  responseType: "stream",
});
r.data.pipe(fs.createWriteStream("out.json"));
```

![Strona httpbin.org/ip pokazuje cztery błędy proxy w Node.js: konfiguracja proxy w axios zwracająca twoje prawdziwe IP lub zawieszająca się, domyślny import agenta, który zgłasza błąd, socks5:// w axios powodujące niezgodność protokołu oraz fetch ignorujący HTTP_PROXY. Karta podaje poprawkę dla każdego z nich, a notatka ostrzega przed jednoczesnym ustawianiem agenta i konfiguracji proxy.](https://res.cloudinary.com/dmqliab0t/image/upload/f_auto,q_auto,w_1200/v1785335146/blog/generated/qp-b9-007-diag2.png)
*Większość awarii proxy w Node.js sprowadza się do pięciu błędów: błąd HTTPS w axios, domyślny import agenta, podwójna konfiguracja proxy, zły schemat SOCKS lub oczekiwanie, że fetch przeczyta zmienne środowiskowe.*

## Najczęściej zadawane pytania

### Dlaczego mój proxy w axios nie działa?

Najczęstszą przyczyną jest cel HTTPS za HTTP proxy: wbudowana konfiguracja `proxy` w axios nie otwiera tunelu CONNECT i zwraca twoje prawdziwe IP lub zawiesza się. Przełącz się na agenta proxy — podłącz `HttpsProxyAgent` do `httpAgent` i `httpsAgent`, i ustaw `proxy: false`, aby axios przestał próbować obsługiwać proxy samodzielnie.

### Czy axios obsługuje proxy SOCKS5?

Nie natywnie — przekazanie URL `socks5://` do konfiguracji `proxy` powoduje błąd niezgodności protokołów. Zainstaluj `socks-proxy-agent`, zbuduj `SocksProxyAgent` i podłącz go do `httpAgent` i `httpsAgent`. Użyj schematu `socks5h://`, aby DNS rozwiązywał się po stronie proxy, a nie wyciekał z twojego komputera.

### Jak używać proxy z natywnym fetch w Node.js?

Natywny fetch nie ma opcji proxy i ignoruje zmienne środowiskowe `HTTP_PROXY`. Utwórz `ProxyAgent` undici i przekaż go jako opcję `dispatcher` w wywołaniu fetch, lub wywołaj `setGlobalDispatcher()` raz, aby proxyzować każdy fetch w procesie. Undici obsługuje HTTPS CONNECT poprawnie bez dodatkowej konfiguracji.

### Jak ustawić proxy w axios za pomocą zmiennych środowiskowych?

Eksportuj `HTTP_PROXY`, `HTTPS_PROXY` i opcjonalnie `NO_PROXY` z pełnymi URL proxy; axios czyta je automatycznie. Ustaw `proxy: false` na żądaniu lub instancji, aby axios ignorował środowisko. Pamiętaj, że to dotyczy tylko axios — undici i natywny fetch nie pobiorą tych zmiennych.

Cała historia mieści się na karcie: axios potrzebuje agenta i `proxy: false`, natywny fetch potrzebuje dyspozytora undici, SOCKS potrzebuje własnego agenta, a rotacja należy do bramy, a nie do twojej pętli. Prawidłowo skonfiguruj hydraulikę, a ostatnią zmienną jest jakość IP — czyste wyjście rezydencjalne przechodzi tam, gdzie oznaczone IP z centrum danych dostaje 403 na tym samym kodzie.

[Zdobądź proxy rezydencjalne, które przechodzą przy pierwszym żądaniu](https://quantumproxies.io/residential-proxies)
