Ngiêm cấm sử đụng PROXY và VPS vào mục đích trái pháp luật bạn sẽ phải chịu toàn bộ trách nhiệm trước pháp luật khi sử dụng dịch vụ của chúng tôi tks!
Ky proxy: dispatcher cho Node.js và giới hạn trình duyệt

Ky proxy: dispatcher cho Node.js và giới hạn trong trình duyệt

Chuyên viên Kỹ thuật ProxyVN 07-21-2026 Đang tính... phút đọc

Ky proxy là cách cho thư viện Ky gửi request qua máy trung gian. Ky chỉ bọc fetch, nên đường mạng phụ thuộc vào nơi fetch chạy: Node.js hay trình duyệt. ProxyVN chạy Ky 2.2.0 và 1.14.3 trên Node 24 qua proxy tự dựng, thử thêm trong Edge, rồi ghi lại cấu hình nào thật sự đổi đường đi.

Ky proxy bắt đầu từ việc hiểu Ky là gì

Ky chỉ là lớp bọc quanh fetch

Ky chỉ bọc fetch

Ky chỉ bọc fetch

Ky là thư viện HTTP nhỏ của Sindre Sorhus, viết trên Fetch API. Nó thêm các tiện ích như thử lại, timeout, hooks, tạo instance và đọc JSON gọn hơn. Ky không tự mở kết nối TCP, không có tầng mạng riêng. Mọi request cuối cùng đều được giao cho hàm fetch của môi trường đang chạy.

Điểm này quyết định toàn bộ cách cấu hình proxy. Trong Node.js, fetch tích hợp dựa trên Undici, và Undici nhận một tùy chọn tên dispatcher để chọn đường đi. Trong trình duyệt, fetch do chính trình duyệt điều khiển, mã JavaScript của trang không có quyền chọn proxy.

Trước khi cấu hình, xác định Ky đang chạy trên môi trường nào. Trả lời được câu đó thì cách cài proxy gần như tự rõ.

Vì sao tên Ky dễ gây nhầm khi tìm tài liệu

Khi rà các bài cũ của ProxyVN, mình gặp nhiều chuỗi chứa ky như 32-ky-tu hay tu-ky. Đó là tiếng Việt không dấu, không liên quan tới thư viện. Khi tìm lỗi trên mạng, anh em nên thêm từ khóa npm hoặc sindresorhus để kết quả đúng thư viện.

Ky cũng hay bị nhầm với Got vì cùng tác giả. Got chạy riêng cho Node.js và dùng agent của module http. Ky chạy được cả trình duyệt, Node.js, Bun, Deno và dùng fetch. Hai cơ chế proxy vì thế khác hẳn nhau, không chép cấu hình qua lại được.

Ranh giới với bài fetch và Axios

Bài Node.js fetch proxy đã nói về fetch tích hợp và Undici ở mức chung. Bài Axios proxy nói về tùy chọn proxy riêng của Axios. Bài này chỉ đi vào phần riêng của Ky: cách Ky chuyển tùy chọn xuống fetch và khác biệt giữa Ky 1 với Ky 2. Bài cũng nói cách lỗi proxy bị bọc lại và lý do cấu hình mất tác dụng trong trình duyệt.

Môi trường thử Ky proxy

Phiên bản đã dùng

Lab chạy trên Windows 10, Node 24.20 với Undici tích hợp bản 7.29.0. Mình cài hai bộ riêng: Ky 2.2.0 là bản mới nhất trên npm ngày 27/10/2026, và Ky 1.14.3 để so. Gói undici cài thêm để lấy ProxyAgent, thử cả bản 7.30.1 và 8.12.3.

mkdir ky-proxy-lab && cd ky-proxy-lab
npm init -y
npm i ky@2.2.0 undici@7.30.1

Phiên bản undici ở đây quan trọng hơn anh em nghĩ. Phần sau sẽ cho thấy một bản undici mới hơn bản tích hợp trong Node làm hỏng toàn bộ request.

Proxy và website thử

Mình dựng một chương trình Python nghe ba cổng. Cổng 8911 là website thử, cổng 8912 là proxy HTTP cần tài khoản user1 với mật khẩu p@ss#2026, cổng 8913 là proxy SOCKS5. Mọi kết nối tới proxy được ghi vào tệp nhật ký.

Website thử tên shop.test, chỉ phân giải được bên trong proxy. Request nào đi thẳng sẽ lỗi DNS. Request nào qua proxy sẽ nhận JSON có đường dẫn và User-Agent. Cách dựng này giúp phân biệt rõ đi thẳng với đi qua proxy mà không cần đoán.

Phần trình duyệt dùng Edge chạy không giao diện, mở một trang cục bộ có lệnh fetch tới shop.test. Mình chạy hai lần, một lần không cờ proxy và một lần có cờ --proxy-server.

Cấu hình Ky proxy trong Node.js bằng dispatcher

Ky chuyển dispatcher xuống fetch

README của Ky trên GitHub ghi rằng Ky chuyển mọi tùy chọn nó không nhận ra xuống fetch. README cũng có mục riêng cho dispatcher, nhận Agent hoặc Dispatcher của Undici và đưa nguyên cho fetch. Nhờ vậy cách gắn proxy rất ngắn.

import ky from 'ky';
import {ProxyAgent} from 'undici';
 
const dispatcher = new ProxyAgent(process.env.PROXY_URL);
const data = await ky('http://shop.test:8911/b', {dispatcher, retry: 0}).json();
console.log(data);

Với PROXY_URL là http://user1:p%40ss%[email protected]:8912, request trả về path /b, User-Agent là node. Nhật ký proxy ghi một lệnh CONNECT tới shop.test:8911 với user1, xác thực đạt. Cùng đoạn mã bỏ dispatcher thì lỗi DNS, chứng tỏ request đi thẳng.

ProxyAgent của Undici làm gì

Tài liệu ProxyAgent của Undici mô tả đây là dispatcher mở kết nối tới proxy rồi xin proxy nối tiếp tới đích. Trong lab, kể cả URL http:// cũng đi bằng CONNECT, giống hpagent bên Got. Proxy chỉ thấy tên máy và cổng đích, không đọc được nội dung request.

ProxyAgent nhận URL proxy có tài khoản, tự tách tên và mật khẩu rồi gửi tiêu đề Proxy-Authorization. Mật khẩu có @ hay # phải mã hóa phần trăm như ví dụ trên. Bài định dạng proxy có bảng chuyển từ ip:port:user:pass sang dạng URL.

Một ProxyAgent giữ bể kết nối tới proxy. Tạo nó một lần rồi dùng lại, đừng tạo mới mỗi request. Tạo mới liên tục sẽ mở nhiều kết nối thừa và dễ chạm hạn mức luồng của gói proxy.

Gắn dispatcher vào instance với ky.create

Trong dự án, cách gọn là tạo một instance với dispatcher, timeout và retry đặt sẵn. Ky 2 đổi tên tùy chọn tiền tố đường dẫn: README hiện hành dùng prefix và baseUrl, còn Ky 1.14.3 dùng prefixUrl. Mình đã chạy cả hai bản với cùng logic.

import ky from 'ky';
import {ProxyAgent} from 'undici';
 
export const api = ky.create({
    prefix: 'http://shop.test:8911',
    dispatcher: new ProxyAgent(process.env.PROXY_URL),
    timeout: 4000,
    retry: {limit: 2, methods: ['get'], statusCodes: [503]},
    hooks: {
        beforeRetry: [({retryCount, error}) => console.log('retry', retryCount, error.name)]
    }
});

Với Ky 1.14.3, thay prefix bằng prefixUrl. Các ca GET, POST, redirect và 503 ở phần sau đều chạy qua instance này. Nhật ký proxy ghi đủ số CONNECT tương ứng với mỗi lần gửi, kể cả các lần thử lại.

Ky proxy với biến môi trường trong Node 24

NODE_USE_ENV_PROXY thay cho mã

Node.js từ 24.5 hỗ trợ đọc HTTP_PROXY và HTTPS_PROXY cho fetch tích hợp khi bật biến NODE_USE_ENV_PROXY=1. README của Ky cũng nhắc mốc Node 24.5 cho hỗ trợ proxy theo biến môi trường. Vì Ky dùng fetch tích hợp, Ky hưởng luôn tính năng này mà không cần dispatcher.

Mình chạy cùng một tệp gọi ky('http://shop.test:8911/env') hai lần. Lần đầu chỉ đặt HTTP_PROXY, request lỗi DNS vì Node bỏ qua biến này. Lần hai thêm NODE_USE_ENV_PROXY=1, request qua proxy và nhận đúng JSON.

NODE_USE_ENV_PROXY=1 HTTP_PROXY='http://user1:p%40ss%232026@127.0.0.1:8912' node app.mjs

Trên PowerShell, đặt biến bằng $env:NODE_USE_ENV_PROXY='1' trước khi chạy node. Tài liệu dòng lệnh Node.js liệt kê biến này trong mục biến môi trường.

Khi nào nên dùng biến môi trường

Biến môi trường hợp với công cụ chạy một lần, script trong CI hay khi không muốn sửa mã. Mọi fetch trong tiến trình đều theo một proxy, kể cả fetch của thư viện khác. Điều đó vừa tiện vừa rủi ro, vì có thể đẩy cả request tới API nội bộ ra proxy.

Với ứng dụng cần nhiều proxy khác nhau, hoặc cần một số request đi thẳng, dispatcher trong mã cho anh em kiểm soát từng instance. NO_PROXY cũng được Node đọc khi bật chế độ này. Bài no_proxy là gì giải thích quy ước viết danh sách bỏ qua.

Không lẫn hai cơ chế

Nếu đã bật NODE_USE_ENV_PROXY rồi lại truyền dispatcher, dispatcher của request sẽ quyết định đường đi cho request đó. Mình khuyên chọn một trong hai và ghi rõ trong README dự án. Lẫn cả hai làm người sau không biết request nào đi đường nào, nhất là khi gỡ lỗi trên máy chủ.

Bẫy phiên bản undici khi dùng Ky proxy

undici phải cùng bản lớn với Node

undici phải cùng bản lớn với Node

undici 8 làm hỏng mọi request

Đây là lỗi mất thời gian nhất trong lab. Khi cài [email protected], bản mới nhất trên npm, rồi truyền ProxyAgent của nó cho Ky chạy trên Node 24.20, mọi request đều lỗi. Ky 2.2.0 báo NetworkError với thông điệp Request failed due to a network error.

Lần theo chuỗi cause, mình thấy TypeError fetch failed, rồi tới gốc là InvalidArgumentError mã UND_ERR_INVALID_ARG, thông điệp invalid onRequestStart method. Nghĩa là ProxyAgent của undici 8 dùng giao diện handler mới, còn fetch tích hợp trong Node 24 vẫn là undici 7.29 và gọi theo giao diện cũ.

ProxyAgent phải cùng dòng bản lớn với Undici tích hợp trong Node. Kiểm bằng lệnh node -p process.versions.undici rồi cài gói undici cùng bản lớn. Trong lab, undici 7.30.1 chạy tốt với Node 24.20.

Hàm fetch tự viết và đối tượng Request

Ky có tùy chọn fetch để thay hàm fetch mặc định. Một cách nghĩ tự nhiên là truyền fetch của gói undici kèm dispatcher. Mình thử đúng cách đó với Ky 1.14.3 và nhận lỗi ERR_INVALID_URL, thông điệp Invalid URL.

Lý do là Ky tạo đối tượng Request của môi trường rồi truyền vào hàm fetch. fetch của gói undici không nhận ra Request đó là Request của nó, nên đọc sai thành chuỗi URL. Khi đổi sang fetch tích hợp kèm dispatcher, request chạy bình thường.

const api = ky.create({
    fetch: (input, options) => fetch(input, {...options, dispatcher})
});

Trong đa số trường hợp không cần tới cách này, vì truyền thẳng dispatcher đã đủ. Chỉ dùng tùy chọn fetch khi cần thêm ghi log hay đo thời gian ở tầng fetch.

Bảng kết quả theo phiên bản

Bảng dưới gom kết quả lab, chỉ đúng với các bản đã ghi.

Bảng: Bảng kết quả theo phiên bản

Cấu hình

Kết quả trong lab

Ky 2.2.0, không dispatcher

Lỗi DNS, đi thẳng

Ky 2.2.0 + ProxyAgent undici 7.30.1

Qua proxy, CONNECT, xác thực đạt

Ky 2.2.0 + ProxyAgent undici 8.12.3

NetworkError, gốc là invalid onRequestStart method

Ky 1.14.3 + fetch của gói undici

ERR_INVALID_URL

Ky 1.14.3 + fetch tích hợp kèm dispatcher

Qua proxy

Chỉ HTTP_PROXY

Lỗi DNS, đi thẳng

HTTP_PROXY + NODE_USE_ENV_PROXY=1

Qua proxy

Bảng này cho thấy lỗi Ky proxy phần nhiều là lệch phiên bản hoặc lệch cơ chế, ít khi do bản thân proxy. Khi nâng Node hay undici, chạy lại các dòng trên trước khi triển khai.

Đọc lỗi Ky proxy: 407, timeout, retry

Lỗi 407 bị bọc ba lớp

Với mật khẩu sai, Ky 2.2.0 báo NetworkError. Bên dưới là TypeError fetch failed, rồi Error Request was cancelled, rồi AbortError mã UND_ERR_ABORTED với thông điệp Proxy response (407) !== 200 when HTTP Tunneling. Chỉ lớp cuối cùng mới nói rõ proxy từ chối tài khoản.

Vì vậy mã xử lý lỗi cần đi hết chuỗi cause. Đoạn dưới in toàn bộ chuỗi, đủ để nhận ra 407 trong nhật ký máy chủ.

try {
    await api.get('items').json();
} catch (error) {
    let e = error;
    while (e) {
        console.error(e.name, e.code ?? '', e.message);
        e = e.cause;
    }
}

Ky 1.14.3 bọc lỗi khác: nó ném thẳng TypeError fetch failed, không có lớp NetworkError. Nếu dự án kiểm error instanceof TypeError, khi nâng lên Ky 2 cần sửa lại. Nguyên nhân phía nhà cung cấp của lỗi 407 có trong bài sửa lỗi 407 Proxy Authentication Required.

HTTPError chỉ dành cho website

Khi website trả 503, Ky ném HTTPError với thông điệp Request failed with status code 503 Service Unavailable kèm phương thức và URL. Lỗi này nghĩa là request đã đi qua proxy và tới được website. Đừng nhầm nó với lỗi proxy.

Quy tắc nhận diện rất gọn: HTTPError là website trả lời, NetworkError hay TypeError là chưa tới được website. Trong nhóm sau, tìm chữ Proxy response trong chuỗi cause để biết lỗi ở proxy.

Timeout và thử lại

README của Ky ghi timeout mặc định là 10000 ms cho mỗi lần thử. Với đường dẫn /slow chờ 5 giây và timeout 2000 ms, Ky báo TimeoutError, thông điệp Request timed out kèm URL. Đây là lỗi riêng của Ky, không bị bọc như lỗi mạng.

Retry mặc định thử 2 lần với các phương thức get, put, head, delete, options, trace và query, mã HTTP 408, 413, 429, 500, 502, 503 và 504. Trong lab, đường dẫn /status/503 được thử 2 lần rồi mới báo lỗi. POST với json {sku: 'A1'} chỉ gửi một lần, website nhận đúng thân request.

Ky không thử lại POST theo mặc định. Đó là hành vi đúng: gửi lại một đơn hàng qua proxy chập chờn có thể tạo hai đơn.

Với lỗi mạng như proxy từ chối kết nối, Ky cũng thử lại theo giới hạn. Khi proxy chết hẳn, mỗi request sẽ tốn ba lần chờ. Đặt timeout ngắn cho lần thử để tiến trình không treo lâu.

Ky proxy với SOCKS5 qua Undici

SOCKS5 trong Undici còn thử nghiệm

Undici 7.30.1 nhận URL socks5:// trong ProxyAgent. Khi chạy, Node in cảnh báo ExperimentalWarning: SOCKS5 proxy support is experimental and subject to change. Mình thử với proxy SOCKS5 cùng tài khoản user1 và mật khẩu p@ss#2026 đã mã hóa phần trăm, kết quả là lỗi UND_ERR_SOCKS5_AUTH_FAILED.

Để tách nguyên nhân, mình dựng thêm proxy SOCKS5 với mật khẩu chỉ gồm chữ và số. Lần này request qua proxy, nhật ký ghi lệnh CONNECT với kiểu địa chỉ domain. Mình suy ra bản undici này chưa giải mã phần trăm phần mật khẩu khi dùng SOCKS5, nhưng chưa đọc mã nguồn để khẳng định.

Khuyến nghị cho dự án thật

Vì tính năng còn thử nghiệm, mình không khuyên dùng SOCKS5 qua Undici cho hệ thống đang chạy. Nếu gói proxy có cả cổng HTTP và SOCKS5, chọn cổng HTTP cho Ky. Nếu bắt buộc SOCKS5, dùng mật khẩu không có ký tự đặc biệt và ghim đúng bản undici đã thử.

Khi nào nên chọn SOCKS5 và khi nào HTTP đủ dùng, bài proxy HTTP và SOCKS5 có so sánh chi tiết. Với Ky, hướng dẫn proxy HTTP đơn giản và ít rủi ro hơn.

Ky proxy trong trình duyệt

Trình duyệt quyết định đường đi

Trình duyệt quyết định đường đi

Trang web không chọn được proxy

Khi Ky chạy trong trình duyệt, nó gọi window.fetch. Theo tài liệu Fetch API trên MDN, các tùy chọn của fetch xoay quanh phương thức, tiêu đề, thân, chế độ CORS, cookie và bộ nhớ đệm. Không có tùy chọn nào chọn proxy. Đường mạng do trình duyệt và hệ điều hành quyết định.

Mình thử bằng Edge không giao diện. Trang cục bộ gọi fetch tới shop.test kèm một tùy chọn dispatcher giả. Chạy không cờ proxy, trang báo Failed to fetch vì không phân giải được shop.test. Chạy với --proxy-server trỏ về proxy thử, fetch hoàn tất và nhật ký proxy ghi GET http://shop.test:8931/from-browser. Tùy chọn dispatcher không làm thay đổi gì, đường đi chỉ đổi khi trình duyệt có cờ proxy.

Đổi proxy ở cấp trình duyệt

Vì thế, muốn Ky trong trang web đi qua proxy, anh em cài proxy cho trình duyệt hoặc hệ điều hành. Với Chrome và Edge, có thể dùng cờ --proxy-server khi mở trình duyệt, cài proxy hệ thống, hoặc dùng tiện ích quản lý proxy. Bài cài proxy cho Google Chrome có các bước cụ thể.

Với kiểm thử tự động, Playwright hay Puppeteer cho phép đặt proxy khi khởi chạy trình duyệt, nên Ky trong trang sẽ đi theo. Đây là cách duy nhất để thử mã Ky phía trình duyệt qua nhiều vùng IP khác nhau.

Cẩn thận với mã dùng chung

Nhiều dự án dùng chung một tệp tạo instance Ky cho cả máy chủ và trình duyệt. Nếu tệp đó nhập undici, bản build cho trình duyệt sẽ lỗi hoặc phình to. Cách an toàn là tạo dispatcher trong tệp chỉ chạy phía máy chủ, rồi truyền vào ky.create qua tham số.

Một mẹo khác là kiểm typeof window trước khi nhập undici bằng import động. Tuy nhiên, tách hai tệp riêng dễ hiểu hơn và tránh lỗi đóng gói khó dò.

Đưa Ky proxy vào dự án Node.js

Cấu trúc gợi ý

Khi đã qua các ca thử, mình gom cấu hình mạng vào một chỗ để mã nghiệp vụ chỉ nhập instance.

  • server/net.js: đọc biến môi trường, mã hóa tài khoản, tạo một ProxyAgent duy nhất.
  • server/api.js: gọi ky.create với dispatcher, timeout, retry và hooks ghi log.
  • test/ip.test.js: gọi trang trả IP, so với IP proxy mong đợi, chạy đầu tiên trong CI.

Ghi rõ trong package.json bản Node tối thiểu và bản undici đã ghim. Bẫy undici 8 ở trên cho thấy nâng gói tự do có thể làm hỏng cả hệ thống mà không có thay đổi nào trong mã.

Ca kiểm IP chạy trước mọi thứ

Ca kiểm IP là cách nhanh nhất để biết cấu hình proxy có tác dụng hay không. Ý tưởng là gọi một trang trả về IP công khai qua instance có proxy, rồi so với IP mong đợi của gói. Đoạn dưới là ví dụ triển khai, anh em thay URL bằng dịch vụ trả IP mà dự án tin dùng.

import assert from 'node:assert/strict';
import {api} from '../server/api.js';
 
const {ip} = await api.get('https://api.ipify.org?format=json', {prefix: undefined}).json();
assert.notEqual(ip, process.env.SERVER_PUBLIC_IP, 'Request dang di thang, chua qua proxy');
console.log('IP ra:', ip);

Nếu IP ra trùng IP máy chủ, dừng toàn bộ pipeline ngay. Lỗi này thường do quên dispatcher, lệch bản undici hoặc tưởng biến HTTP_PROXY đã có tác dụng. Chạy ca này đầu tiên trong CI giúp phát hiện sớm, trước khi hàng nghìn request đi ra bằng IP thật của máy chủ. Mình cũng chạy lại ca này mỗi khi nâng Node, nâng undici hoặc đổi nhà cung cấp proxy, vì cả ba thay đổi đều từng làm hỏng đường đi trong lab mà mã nghiệp vụ không đổi một dòng.

Với Ky 1, tham số tương ứng là prefixUrl. Khi instance có tiền tố đường dẫn, URL đầy đủ có thể xung đột với tiền tố tùy bản, nên mình tạo riêng một instance không tiền tố cho ca kiểm IP nếu gặp lỗi.

Chọn loại proxy cho Ky

Ky hay được dùng để gọi API REST và lấy JSON. Với API yêu cầu IP cố định trong danh sách cho phép, proxy tĩnh là lựa chọn hợp lý. Với việc lấy dữ liệu từ nhiều trang công khai, proxy xoay giúp chia tải, nhưng cần tạo ProxyAgent mới khi đổi phiên.

ProxyVN cung cấp proxy dân cư tĩnh, datacenter và proxy xoay, hỗ trợ HTTP và SOCKS5, cấp tài khoản user và mật khẩu. Nếu cần một gói để chạy đúng cấu hình đã thử ở trên, anh em có thể mua proxy giá rẻ tại trang chủ ProxyVN rồi chạy lại ca kiểm IP trước khi gọi API thật.

Giữ bí mật và dọn dẹp

Không ghi chuỗi proxy có mật khẩu vào mã hay tệp .env được commit. Trên CI, đưa tài khoản vào mục secret. Trong log lỗi, chỉ in tên máy proxy, không in URL đầy đủ.

Sau khi thử xong, xóa thư mục hồ sơ trình duyệt tạm, xóa lịch sử lệnh có chuỗi proxy. Nếu đã dùng tài khoản proxy thật để thử, đổi mật khẩu hoặc thu hồi tài khoản đó.

Ky proxy khi lấy dữ liệu nhiều trang

Giới hạn số request song song

Ky không có bộ giới hạn đồng thời riêng. Nếu anh em gọi Promise.all với hàng trăm URL, toàn bộ sẽ được gửi gần như cùng lúc qua một ProxyAgent. Gói proxy có hạn mức luồng sẽ bắt đầu từ chối, thường dưới dạng 407, 429 hoặc ngắt kết nối giữa chừng.

Cách đơn giản là chia URL thành từng lô nhỏ, chờ lô trước xong mới gửi lô sau. Đoạn dưới là ví dụ triển khai chung, không lấy từ tài liệu Ky.

async function inBatches(urls, size, fn) {
    const out = [];
    for (let i = 0; i < urls.length; i += size) {
        const batch = urls.slice(i, i + size);
        out.push(...await Promise.allSettled(batch.map(fn)));
    }
    return out;
}
 
const results = await inBatches(urls, 5, (url) => api.get(url).json());

Promise.allSettled giữ kết quả của cả request lỗi, nên một URL hỏng không làm mất cả lô. Kích thước lô nên bằng hoặc thấp hơn số luồng gói proxy cho phép. Mình chưa thử các tùy chọn giới hạn kết nối của ProxyAgent, nên chia lô ở tầng mã là cách mình đã chạy.

Ghi log từng request bằng hooks

Khi chạy hàng nghìn request, anh em cần biết request nào chậm, request nào bị thử lại. Ky có hooks beforeRequest, afterResponse và beforeRetry. Mình dùng beforeRetry trong lab để in số lần thử và tên lỗi, đủ để thấy 503 được thử lại 2 lần.

Một hook afterResponse ghi mã trạng thái và thời gian giúp phát hiện sớm IP bị website hạn chế. Khi tỷ lệ 403 hay 429 tăng đột ngột, đó là dấu hiệu IP proxy đang bị đánh dấu, cần giảm tốc hoặc đổi IP. Bài lỗi 429 khi dùng proxy có các cách xử lý cụ thể.

Đổi IP theo phiên

Proxy xoay thường đổi IP theo tên người dùng có mã phiên hoặc theo một đường dẫn đổi IP. Với kiểu đổi theo tên người dùng, mỗi phiên cần một ProxyAgent riêng vì tiêu đề xác thực gắn vào kết nối. Mình khuyên lưu các ProxyAgent trong Map theo mã phiên, đóng agent cũ bằng phương thức close khi không dùng nữa.

Đóng agent đúng lúc giúp tiến trình Node thoát gọn khi chạy xong, không bị treo vì kết nối giữ sẵn. Nếu script crawl chạy xong mà không thoát, kiểm xem còn ProxyAgent nào chưa đóng.

Câu hỏi thường gặp về Ky proxy

Ky có tùy chọn proxy riêng không. Không. Trong Node.js, anh em truyền dispatcher của Undici hoặc bật NODE_USE_ENV_PROXY=1. Trong trình duyệt, proxy do trình duyệt quyết định.

Vì sao đặt HTTP_PROXY mà Ky vẫn đi thẳng. Node 24 chỉ đọc biến này cho fetch khi có NODE_USE_ENV_PROXY=1. Trong lab, thiếu biến đó thì request lỗi DNS.

Cài undici bản nào. Cùng bản lớn với Undici tích hợp trong Node. Với Node 24.20, undici 7.30.1 chạy được, undici 8.12.3 báo invalid onRequestStart method.

Lỗi 407 hiện ở đâu. Ở lớp cuối của chuỗi cause, thông điệp Proxy response (407) !== 200 when HTTP Tunneling. Lớp ngoài chỉ là NetworkError hoặc TypeError fetch failed.

Ky có thử lại POST không. Không theo mặc định. Danh sách phương thức thử lại không có post.

Dùng Ky trong tiện ích trình duyệt thì sao. Vẫn là fetch của trình duyệt. Tiện ích có quyền proxy có thể đổi proxy cho trình duyệt, nhưng đó là API của tiện ích, không phải tùy chọn của Ky.

Checklist Ky proxy trước khi triển khai

Checklist Ky proxy trước khi triển khai

Checklist Ky proxy trước khi triển khai

Tám điểm cần kiểm

Danh sách dưới đây bao gồm hầu hết lỗi đã gặp trong lab.

  • Biết Ky chạy ở đâu: Node.js thì dùng dispatcher, trình duyệt thì cài proxy cho trình duyệt.
  • undici cùng bản lớn với Node: kiểm process.versions.undici trước khi cài.
  • Một ProxyAgent dùng lại, không tạo mới mỗi request.
  • Mật khẩu đã mã hóa phần trăm trong URL proxy HTTP.
  • Ky 2 dùng prefix, Ky 1 dùng prefixUrl.
  • Xử lý lỗi đi hết chuỗi cause để thấy Proxy response (407).
  • Timeout ngắn cho mỗi lần thử, vì mặc định 10 giây nhân với số lần thử lại.
  • Không dùng SOCKS5 thử nghiệm cho hệ thống đang chạy.

Những gì chưa thử

Mình chưa thử Ky trên Bun hay Deno, chưa thử proxy kết nối bằng TLS, chưa thử HTTP/2 qua proxy và chưa thử với gateway thương mại. Phần trình duyệt chỉ thử với Edge không giao diện trên Windows, chưa thử Firefox hay Safari.

Kết quả có thể khác ở các bản Node khác. Khi Node chuyển sang undici 8 tích hợp, bẫy phiên bản ở trên sẽ đảo chiều, lúc đó undici 7 mới là bản lệch. Hãy chạy lại bảng kết quả với đúng phiên bản của mình.

Ky proxy và những điều cần nhớ

Ky proxy phụ thuộc nơi fetch chạy. Trong Node.js, truyền ProxyAgent cùng bản lớn với Undici tích hợp, hoặc bật NODE_USE_ENV_PROXY=1. Trong trình duyệt, chỉ cài proxy cho trình duyệt mới có tác dụng. Đọc hết chuỗi cause để thấy lỗi 407. Cần proxy ổn định cho Ky proxy, liên hệ Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam.

TIN TỨC LIÊN QUAN