Konuyla doğrudan ilgimiz var: Biz Geonode olarak proxy satıyoruz; dolayısıyla bu, bizim türden bir ürünü kullanmaya yönelik bir kılavuzdur. Buradaki en yararlı ipucu hiçbir maliyeti yok — yapılandırma yaptıktan sonra her seferinde çıkış adresini doğrulayın. Etkiye girmeyen bir proxy ayarı ne hata ne uyarı ne de başarısız istek üretir. Doğrudan hedefe giden, çalışan bir istek üretir ve kullanıcılar haftalarca bu durumda çalışmaya devam ederler. Doğrulama bölümü kısadır ve diğer her şeyi atlasanız bile mutlaka okumanız gereken kısım budur.
Ayrıca, axios’un yalnızca Node’da proxy’leri desteklediğini unutmayın. Tarayıcıda XMLHttpRequest kullanır ve proxy ayarlama yeteneği yoktur; proxy seçeneği sessizce yok sayılır.
proxy
Yapılandırma Seçeneği
Yerleşik yaklaşım ve doğru varsayılan ayar.
import axios from "axios";
const res = await axios.get("https://api.example.com/items", {
proxy: {
protocol: "http",
host: "proxy.example.com",
port: 9000,
auth: {
username: "myuser",
password: "mypass",
},
},
});
Axios belgeleri, bu yapıyı protocol
, host
, hostname
, port
ve username
ile password
öğelerini içeren bir auth
nesnesi ile açıklamaktadır. Bilinmesi gereken bir ayrıntı: "hostname" takes precedence over "host" if both are defined
; bu, bir şeyi yapılandırırken yanlışlıkla her ikisini de ayarladığınızda, bir tanesini kullanıp diğerini devre dışı bırakmanın sessiz bir yoludur.
Alanlarla ilgili iki nokta.
**protocol
, hedefe nasıl ulaşacağınız değil, proxy'ye nasıl ulaşacağınızla ilgilidir**. CONNECT
tüneli üzerinden HTTPS trafiğini işleyen sıradan bir HTTP proxy için, isteğinizin URL'si https://.
olsa bile protocol
, "http"
olur. Bunu "https"
olarak ayarlamak, proxy'nin kendisine TLS kullanılması anlamına gelir; ancak çoğu proxy bu özelliği sunmaz.
**auth
yapılandırılmış bir nesnedir**; bir başlık değildir ve URL'nin bir parçası değildir. Bu, gerçek bir kolaylıktır — şifresinde @
, :
veya /
bulunan kullanıcıların karşılaştığı yüzde kodlama sorununu ortadan kaldırır.
Bunu her isteğe uygulamak için bir örnekte ayarlayın:
const client = axios.create({
baseURL: "https://api.example.com",
proxy: { protocol: "http", host: "proxy.example.com", port: 9000,
auth: { username: "myuser", password: "mypass" } },
timeout: 30000,
});
Ortam Değişkenleri
Axios, geleneksel değişkenleri destekler; bu özelliği, onu Node'un yerleşik fetch
'sinden ayırır.
Belgelerde, "http_proxy
ve https_proxy
gibi geleneksel ortam değişkenlerini kullanarak da proxy'nizi tanımlayabilirsiniz" ve "no_proxy
ortam değişkenini, proxy'ye tabi tutulmaması gereken etki alanlarının virgülle ayrılmış bir listesi olarak da tanımlayabilirsiniz" denilmektedir.
export http_proxy=http://myuser:mypass@proxy.example.com:9000
export https_proxy=http://myuser:mypass@proxy.example.com:9000
export no_proxy=localhost,127.0.0.1,.internal
Bu, proxy'nin uygulama düzeyinde değil ortam düzeyinde bir konu olduğu konteyner tabanlı dağıtımlar ve CI için geçerli bir yaklaşımdır — kod değişikliği gerekmez ve bu kuralı uygulayan konteyner içindeki her araç için aynı yapılandırma geçerlidir.
Üç pratik not.
Küçük harf kullanın. CGI benzeri ortamlarda büyük harfli HTTP_PROXY
kullanımı özel bir tehlike arz eder; bu ortamlarda istek başlıkları büyük harfli ortam değişkenlerine dönüşür ve bu kuralı uygulayan bir istemci, saldırgan tarafından sağlanan Proxy:
başlığıyla yönlendirilebilir. Küçük harf kullanımı bu sorunu ortadan kaldırır.
**no_proxy
adresinde virgül sonrası boşluk kullanılmamalıdır.** Başındaki boşluk, ana bilgisayar adının bir parçası haline gelir ve giriş, fark edilmeden eşleşmez. Bu, tüm dillerde en sık görülen no_proxy
hatasıdır.
Şifredeki özel karakterleri yüzde kodlayın. URL'deki kimlik bilgileri URL ayrıştırmasına tabidir, bu nedenle p@ss
yanlış yerde bölünür. proxy
yapılandırma nesnesi bunu tamamen önler; bu da mümkün olduğunda onu tercih etmeniz için bir nedendir.
Belirli bir istek için ortam değişkenlerini yok saymak isterseniz, belgelerde açıkça şöyle belirtilmiştir: "false
'i kullanarak proxy'leri devre dışı bırakın ve ortam değişkenlerini yok sayın."
const res = await axios.get(url, { proxy: false });
Bu gerçekten kullanışlıdır — dahili bir hizmete yönelik durum kontrolü yapmak veya hiçbir ayarı genel olarak sıfırlamadan yönlendirilmemesi gereken tek bir istek göndermek gibi durumlarda.
Özel Aracılar
Üçüncü yol; yerleşik seçenek yeterli olmadığında başvurulması gereken yöntem budur.
import axios from "axios";
import { HttpsProxyAgent } from "https-proxy-agent";
const agent = new HttpsProxyAgent("http://myuser:mypass@proxy.example.com:9000");
const res = await axios.get("https://api.example.com/items", {
httpsAgent: agent,
proxy: false,
});
proxy: false'si önemlidir. Bu ayar olmadan, aynı anda iki proxy mekanizması yapılandırılmış olabilir ve hangisinin geçerli olacağı konusunda belirsizlik yaşamak istemezsiniz. Yerleşik seçeneği devre dışı bırakmak, sorumluluğun kesin olarak aracıya ait olmasını sağlar.
Belgelerde, httpAgent ve httpsAgent seçeneklerinin "varsayılan olarak etkinleştirilmemiş keepAlive gibi seçeneklerin eklenmesine" izin verdiği belirtilmektedir; bu da bunları kullanmanın ana nedenini ortaya koymaktadır:
Bağlantı yeniden kullanımı. İstekler arasında Keep-alive özelliği, aynı ana bilgisayara çok sayıda çağrı yapan her şey için önemli bir performans farkı yaratır ve varsayılan olarak etkin değildir.
SOCKS desteği. Yerleşik proxy seçeneği, HTTP proxy'lerini yönetir. SOCKS için ise, bu amaçla tasarlanmış bir paketten bir aracıya ihtiyacınız vardır.
Aracı başına havuz oluşturma. Farklı hedefler için farklı aracılar ve bağımsız bağlantı havuzları.
Bunun karşılığında, bir bağımlılık ortaya çıkar ve biraz daha fazla düşünmek gerekir. Basit gereksinimleri olan tek bir HTTP proxy için, yerleşik seçenek daha basittir ve işi görür.
Gerçekten Çalışıp Çalışmadığını Doğrulayın
En önemli kısım budur ve çoğu kişi bu adımı atlar.
const res = await axios.get("https://api.ipify.org?format=json", {
proxy: { protocol: "http", host: "proxy.example.com", port: 9000,
auth: { username: "u", password: "p" } },
});
console.log(res.data);
Proxy yapılandırılmış ve yapılandırılmamış olarak çalıştırın. Adres değişmezse, proxy yolunda değildir. Sizi uyaran bir hata, uyarı veya başarısız istek yoktur — bu kontrol, çalışan bir yapılandırma ile sessizce atlanan bir yapılandırma arasındaki tek farktır.
Bir yapılandırmanın genellikle hiçbir şey yapmamasının üç nedeni:
Öncelik. İstekteki bir proxy seçeneği, örneği geçersiz kılar; proxy: false seçeneği ise ortamı geçersiz kılar; ayrıca bir aracı, kontrolü tamamen devralabilir. Yapılandırmayı tek bir yerden yapın ve hangisi olduğundan emin olun.
no_proxy'i eşleştirme. Hedefinizi istemeden kapsayan bir giriş veya virgülün ardından yer alan gereksiz bir boşluk.
Başka bir yerde zaten ayarlanmış bir aracı. Proxy desteği olmayan bir örnekte httpsAgent yapılandırılmışsa, bağlantıyı bu aracı yönetir ve proxy seçeneği atlanır.
Coğrafi hedeflemeli proxy'ler için adres kontrolü yeterli değildir. Sonuca göre doğrulayın — bölgelere göre gerçekten farklılık gösteren bir şey isteyin ve değiştiğini teyit edin. API'niz kendi bölgenizin verilerini döndürürken doğru ülkeyi bildiren bir arama, hedeflemenin olması gereken yere ulaşmadığı anlamına gelir; bu da proxy'leri test etmenin neden önemli olduğu başlıklı yazımızda bahsettiğimiz "sessiz hata" örneğidir.
Proxy Üzerinden Zaman Aşımları ve Hatalar
Herhangi bir şeyin bozuk olduğu sonucuna varmadan önce yapmanız gereken iki ayar vardır.
Zaman aşımını artırın. Axios'un varsayılan bir zaman aşımı değeri yoktur, bu yüzden bir değer belirleyin — ve bunu alışkanlığınıza göre değil, ölçümlere dayanarak yapın. Ev tipi proxy'ler, istek başına gerçek bir gecikme ekler; bu bir arıza değil, fiziksel bir durumdur ve doğrudan bağlantıya göre ayarlanmış bir değer, bozuk bir proxy gibi görünen hatalara neden olur.
const client = axios.create({ timeout: 30000, proxy: { /* ... */ } });
Durum kodunu doğru şekilde yorumlayın. fetch'dan farklı olarak, Axios varsayılan olarak HTTP hata durumlarında isteği reddeder; bu nedenle 407 hatası, err.response.status ile bir hata olarak atılır. İki farklı kimlik doğrulama hatasını birbirinden ayırt edin:
try {
await client.get("/items");
} catch (err) {
const status = err.response?.status;
if (status === 407) throw new Error("Proxy rejected credentials");
if (status === 401) throw new Error("Target requires authentication");
if (!err.response) throw new Error(`Network error: ${err.code} ${err.message}`);
throw err;
}
407 kodu, proxy'nin sizi durdurduğu ve hedefe hiçbir zaman ulaşılamadığı anlamına gelir. 401 kodu ise proxy'nin çalıştığı ve hedefin kimlik bilgilerini istediği anlamına gelir — bu iki durumun çözümleri tamamen farklıdır. Ayrıca, err.response içermeyen bir hata, HTTP yanıtının hiç gelmediği anlamına gelir; bu da, her iki tarafın kimlik doğrulamasından ziyade bağlantı sorununa işaret eder.
Ayrıntılı incelemeye değer yaygın err.code değerleri: ECONNREFUSED, proxy adresinde dinleme yapan hiçbir şeyin olmadığı anlamına gelir; ETIMEDOUT, paketlerin bir yerde düşürüldüğü anlamına gelir; ENOTFOUND ise proxy ana bilgisayar adının çözümlenemediği anlamına gelir.
Örnek Alınmaya Değer Yeniden Kullanılabilir Bir İstemci
Parçaları bir araya getirerek, bir projede gerçekten kullanabileceğiniz bir şey oluşturmak.
import axios from "axios";
const PROXY = process.env.PROXY_HOST
? {
protocol: "http",
host: process.env.PROXY_HOST,
port: Number(process.env.PROXY_PORT),
auth: process.env.PROXY_USER
? { username: process.env.PROXY_USER, password: process.env.PROXY_PASS }
: undefined,
}
: false;
export const client = axios.create({
timeout: 30000,
proxy: PROXY,
headers: { "User-Agent": "AcmeBot/1.0 (+https://acme.example.com/bot)" },
validateStatus: status => status < 500,
});
client.interceptors.response.use(
res => res,
err => {
const status = err.response?.status;
const url = err.config?.url;
if (status === 407) {
return Promise.reject(new Error(`Proxy rejected credentials for ${url}`));
}
if (!err.response) {
return Promise.reject(new Error(`Network error ${err.code} for ${url}: ${err.message}`));
}
return Promise.reject(err);
}
);
export async function verifyProxy() {
const { data } = await client.get("https://api.ipify.org?format=json");
console.log(`Exit address: ${data.ip}`);
return data.ip;
}
Burada açıklanmaya değer beş karar var.
Kimlik bilgileri ortamdan alınır ve proxy isteğe bağlıdır. PROXY, herhangi bir ana bilgisayar yapılandırılmadığında false olarak değerlendirilir; bu da proxy işlevini ortamın içerdiği her ne olursa olsun ona bırakmak yerine açıkça devre dışı bırakır. Bu, yerel geliştirme ve üretim ortamlarının öngörülebilir şekilde çalışmasını sağlar ve kaynak kodda hiçbir zaman kimlik bilgilerinin görünmemesi anlamına gelir.
Axios’ta zaman aşımı ayarı bulunmadığından, burada bir zaman aşımı ayarlanmıştır. Otuz saniye, proxy üzerinden çalışmaya başladıktan sonra ölçülen bir değerle değiştirilebilecek bir başlangıç noktasıdır.
İletişim URL’si içeren gerçek bir kullanıcı ajanı. Bunun hiçbir maliyeti yoktur ve bu, anonim bir istemci ile operatörün izin vermeyi seçebileceği bir istemci arasındaki farkı oluşturur.
validateStatus: status => status < 500, 4xx kodlarını bir istisna değil, bir yanıt olarak ele alır; bu, 404 kodunun bir hata değil de meşru bir sonuç olduğu durumlarda genellikle istediğiniz şeydir. İsteğinize göre ayarlayın — önemli olan, varsayılan ayarı olduğu gibi devralmak yerine bilinçli bir karar vermektir.
Yakalayıcı, hatanın adını belirtir. Bir 407, proxy'nin kimlik bilgilerini reddettiğini belirten bir mesaja dönüşür; bir bağlantı hatası ise hata kodunu ve URL'yi belirtir. Her ikisi de, sabahın üçünde bir günlük kaydında, AxiosError ile biten bir yığın izlemesinden çok daha kullanışlıdır.
Ayrıca verifyProxy() dosyası dışa aktarılır ve başlangıçta çağrılır. Süreç başlatıldığında bunu bir kez çalıştırmak, sessiz bir baypas işlemini günlüklerinizde bir satıra dönüştürür; bu da, bu makalenin ana argümanının altı satırlık koda sıkıştırılmış halidir.
Dönen Proxy'ler
Birden fazla çıkış kullanan her şey için, yapıya ilişkin bir not.
const proxies = [ /* ... */ ];
let i = 0;
function nextClient() {
const p = proxies[i++ % proxies.length];
return axios.create({ proxy: p, timeout: 30000 });
}
Doğru bir şekilde uygulanması gereken üç husus.
Zamanlayıcıya göre değil, arıza durumunda döndürün. Bir sayacın artması nedeniyle adresler arasında geçiş yapmak, havuz kapasitesini boşa harcar ve hiçbir fayda sağlamaz. Belirli bir adres çalışmaz hale geldiğinde döndürün.
Bir oturum için tek bir adresi kullanın. Bir dizi ilişkili istek içeren her şey — oturum açma, çok adımlı akış, oturuma bağlı sayfalandırılmış sonuçlar — baştan sona aynı çıkış noktasına ihtiyaç duyar. Dört farklı ülkeden gelen istekler tek bir oturum sayılmaz.
Toplam olarak değil, proxy başına başarı oranını takip edin. On adreslik bir havuzda arızalı tek bir adres, ortalama rakamda görünmezken adres bazında incelendiğinde açıkça ortaya çıkar.
Çoğu ticari sağlayıcı, rotasyonu ağ geçidinde yönetir; bu durumda, bir uç noktayı yapılandırır ve listeyi kendiniz yönetmek yerine kullanıcı adı veya bağlantı noktası aracılığıyla tercihlerinizi belirtirsiniz. Bu genellikle daha az kod ve daha az hata anlamına gelir.
Axios mu, Yoksa Başka Bir Şey mi?
Kısa bir açıklama: Bu seçim, ne kadarını kullanmanız gerektiğini belirler.
Axios, proxy ortam değişkenlerini destekler; URL kodlama sorunlarını önleyen yapılandırılabilir bir proxy seçeneğine sahiptir; HTTP hatalarında bağlantıyı keser ve JSON’u otomatik olarak çözümler. Node’da proxy kullanımı için, yaygın olarak kullanılan istemciler arasında en kullanışlı olanıdır.
Node'un yerleşik fetch işlevi, HTTP_PROXY dosyasını hiç okumaz — undici'nin ProxyAgent işleviyle bir dağıtıcıyı açıkça ayarlamanız gerekir; bunu unutmak, tam da yukarıda açıklanan sessiz baypas durumuna yol açar. Ayrıca HTTP hatalarında da çözümleme yapar, bu nedenle res.ok dosyasının kontrol edilmesi gerekir.
got ve undici, her ikisi de proxy'leri iyi yönetir ve yüksek verimli işler için dikkate alınmaya değerdir.
Davranış farklılıklarını axios vs fetch başlıklı yazımızda daha kapsamlı bir şekilde karşılaştırdık; proxy yönetimi, aralarındaki en büyük pratik farklardan biridir.
Sık Sorulan Sorular
Axios ile proxy nasıl kullanılır?
İstek veya örnek yapılandırmasında proxy nesnesini, protocol, host, port ve isteğe bağlı olarak username ile password değerlerini içeren auth nesnesiyle birlikte aktarın. Hedef URL https://. olsa bile, sıradan bir HTTP proxy için protocol değerini "http" olarak ayarlayın.
Axios, HTTP_PROXY ortam değişkenlerini dikkate alır mı?
Evet, Node'da. Belgelerde, geleneksel http_proxy ve https_proxy değişkenlerini kullanarak bir proxy tanımlayabileceğiniz ve no_proxy adresini virgülle ayrılmış hariç tutma listesi olarak kullanabileceğiniz belirtilmektedir. Bu, bunları tamamen yok sayan Node'un yerleşik fetch işlevinden farklıdır.
Tek bir istek için proxy'yi nasıl devre dışı bırakabilirim?
proxy: false ayarını yapın; belgelerde bu ayarın proxy'leri devre dışı bıraktığı ve ortam değişkenlerini yok saydığı belirtilmektedir. Bu, genel ayarları değiştirmeden tek bir isteği hariç tutmanın doğru yoludur.
Axios proxy'm neden çalışmıyor?
Çoğu zaman öncelik sorunudur — bir istek düzeyindeki ayarın örnek düzeyindeki ayarı geçersiz kılması, hedefinizle eşleşen bir no_proxy girişi veya başka bir yerde yapılandırılmış bir aracının devreye girmesi gibi. Adresinizi bildiren bir hizmetten istek göndererek bunu doğrulayın, çünkü atlanan bir proxy hiçbir hata üretmez.
Axios ile https-proxy-agent'a ihtiyacım var mı?
Standart bir HTTP proxy için gerekmez — yerleşik proxy seçeneği, HTTPS hedeflerini CONNECT tüneli üzerinden yönetir. SOCKS proxy’leri, bağlantı keep-alive veya ajan başına havuzlama için bir ajana ihtiyacınız vardır. Bir ajan kullandığınızda, iki mekanizmanın birbiriyle çakışmaması için proxy: false ayarını yapın.
Axios'ta proxy kimlik doğrulama hatalarını nasıl ele alabilirim?
Axios, HTTP hata durumlarında isteği reddeder; bu nedenle hatayı yakalayın ve err.response.status adresindeki bilgileri okuyun. 407 hatası, proxy'nin kimlik bilgilerinizi reddettiği anlamına gelir; 401 hatası ise proxy'nin çalıştığını ve hedefin kimlik bilgilerini istediği anlamına gelir. err.response adresinde hata olması, hiçbir HTTP yanıtının gelmediği anlamına gelir.
Axios'u tarayıcıda bir proxy ile kullanabilir miyim?
Hayır. Axios, tarayıcılarda XMLHttpRequest adresini kullanır ve proxy ayarlayamaz — bu seçenek sessizce yok sayılır. Proxy desteği yalnızca Node'da mevcuttur; bu durum, her iki ortam arasında paylaşılan kodlarda sıkça kafa karışıklığına yol açar.
Ortam değişkenlerini mi yoksa config seçeneğini mi kullanmalıyım?
Proxy'nin bir ortam sorunu olduğu ve aynı yapılandırmanın tüm araçlara hizmet ettiği konteyner tabanlı ve CI dağıtımları için ortam değişkenlerini kullanın. Uygulama düzeyinde kontrol için config nesnesini kullanın; çünkü yapılandırılmış auth alanı, şifrelerdeki özel karakterlerle ilgili yüzde kodlama sorunlarını önler.
Sonuç
Axios, proxy’leri çoğu Node istemcisinden daha sorunsuz bir şekilde yönetir: URL kodlamasını ortadan kaldıran yapılandırılmış bir yapılandırma nesnesi, geleneksel ortam değişkenlerinin desteklenmesi ve temiz bir kaçış yolu olarak proxy: false. Çoğu durumda, yerleşik seçenek ihtiyacınızı tam olarak karşılar.
SOCKS, bağlantı canlı tutma veya bağımsız havuzlama gerektiğinde bir ajana başvurun — ve bunu yaptığınızda, hangi mekanizmanın sorumlu olduğu konusunda herhangi bir belirsizlik olmaması için proxy: false ayarını da ekleyin.
Ardından bir zaman aşımı süresini ayarlayın; çünkü axios'un varsayılan olarak zaman aşımı süresi yoktur ve ev tipi proxy'ler, aksi takdirde bir hata gibi görünecek gerçek gecikme süresi ekler. Ayrıca, her hatayı aynı şekilde ele almak yerine err.response?.status adresine yönlendirin; çünkü 407 ve 401 hataları farklı kaynaklardan gelir ve çözümleri farklıdır.
Her şeyden önce, doğrulama yapın. Sessizce hiçbir şey yapmayan bir proxy yapılandırması, çalışan bir yapılandırmadan ayırt edilemez — her iki durumda da istekler başarılı olur — ve adresinizi bildiren bir hizmeti talep eden tek bir satır, bilmekle varsaymak arasındaki tek farktır.