Trong quá trình phát triển ứng dụng Front-end hoặc Full-stack, chắc hẳn bạn đã từng gặp phải lỗi kinh điển: CORS (Cross-Origin Resource Sharing). Hoặc đôi khi, bạn cần gọi một API bên thứ ba nhưng không muốn lộ API Key ở phía Client.
Thay vì phải tốn thời gian setup và duy trì một backend server (Node.js/Express, Laravel...) chỉ để làm trung gian, chúng ta có một giải pháp tối ưu và hoàn toàn miễn phí: Cloudflare Workers.
Bài viết này sẽ hướng dẫn chi tiết cách dùng Cloudflare Workers để tạo một Proxy Server chỉ trong vài phút.
1. Cloudflare Workers Proxy giải quyết bài toán gì?
-
Bypass CORS: Đóng vai trò là cầu nối. Client gọi đến Worker (cùng domain hoặc đã setup CORS), Worker gọi đến API đích (Server-to-Server không bị vướng CORS) và trả data về cho Client.
-
Bảo mật API Key: Giấu các thông tin nhạy cảm (như Authorization Tokens, API Keys) trên Worker thay vì hardcode ở Front-end.
-
Rate Limiting & Caching: Tận dụng mạng lưới Edge Network của Cloudflare để cache response, giảm tải cho server gốc và tăng tốc độ phản hồi.
2. Chuẩn bị
-
Một tài khoản Cloudflare (Miễn phí).
-
Kiến thức cơ bản về JavaScript (ES Modules, Fetch API).
3. Các bước triển khai
Bước 1: Tạo một Cloudflare Worker mới
-
Đăng nhập vào Cloudflare Dashboard.
-
Ở thanh menu bên trái, chọn Workers & Pages > Overview.
-
Bấm nút Create application > chọn tab Workers > bấm Create Worker.
-
Đặt tên cho Worker của bạn (ví dụ:
my-api-proxy) và bấm Deploy. -
Sau khi deploy thành công, bấm vào nút Edit code để mở trình soạn thảo trực tuyến.
Bước 2: Viết logic cho Proxy
Trong trình soạn thảo, bạn sẽ thấy một đoạn code mặc định. Hãy xóa đi và thay thế bằng đoạn code dưới đây.
Trong ví dụ này, chúng ta sẽ tạo proxy để gọi đến một API đích là https://jsonplaceholder.typicode.com.
export default {
async fetch(request, env, ctx) {
// 1. Định nghĩa URL của Server đích (Target API)
const TARGET_URL = "https://jsonplaceholder.typicode.com";
// 2. Phân tích request hiện tại
const url = new URL(request.url);
// Tạo URL mới bằng cách ghép TARGET_URL với path và query string của request gửi lên
const targetUrl = new URL(TARGET_URL + url.pathname + url.search);
// 3. Clone request để gửi đi (giữ nguyên method, headers, body)
// Lưu ý: Tùy chỉnh headers tại đây nếu bạn cần đính kèm API Key ẩn
const modifiedRequest = new Request(targetUrl, {
method: request.method,
headers: request.headers,
body: request.body,
redirect: "manual", // Xử lý redirect thủ công nếu có
});
// Bỏ qua header Origin và Referer để tránh bị server đích chặn (tùy chọn)
modifiedRequest.headers.delete("Origin");
modifiedRequest.headers.delete("Referer");
try {
// 4. Thực hiện gọi API đích
const response = await fetch(modifiedRequest);
// 5. Clone response trả về để có thể chỉnh sửa Headers
const modifiedResponse = new Response(response.body, response);
// 6. Thêm các Headers CORS để Front-end có thể nhận được data mà không bị block
modifiedResponse.headers.set("Access-Control-Allow-Origin", "*");
modifiedResponse.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
modifiedResponse.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
return modifiedResponse;
} catch (error) {
// Xử lý lỗi nếu fetch thất bại
return new Response(JSON.stringify({ error: "Proxy Fetch Failed", details: error.message }), {
status: 500,
headers: { "Content-Type": "application/json" }
});
}
}
};Bước 3: Xử lý Preflight Request (OPTIONS)
Trình duyệt thường gửi một request OPTIONS (Preflight) trước khi gửi request thật (POST, PUT, DELETE, hoặc có custom headers) để kiểm tra CORS. Bạn cần bổ sung logic để Worker bắt và trả lời request này ngay lập tức.
Cập nhật lại toàn bộ file code như sau:
// Cấu hình CORS chung
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
export default {
async fetch(request, env, ctx) {
// Xử lý Preflight Request từ trình duyệt
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204, // No Content
headers: corsHeaders,
});
}
const TARGET_URL = "https://jsonplaceholder.typicode.com";
const url = new URL(request.url);
const targetUrl = new URL(TARGET_URL + url.pathname + url.search);
const modifiedRequest = new Request(targetUrl, {
method: request.method,
headers: request.headers,
body: request.body,
});
try {
const response = await fetch(modifiedRequest);
const modifiedResponse = new Response(response.body, response);
// Gắn CORS headers vào response trả về
Object.keys(corsHeaders).forEach(key => {
modifiedResponse.headers.set(key, corsHeaders[key]);
});
return modifiedResponse;
} catch (error) {
return new Response(JSON.stringify({ error: "Proxy Fetch Failed" }), {
status: 500,
headers: { "Content-Type": "application/json", ...corsHeaders }
});
}
}
};Bước 4: Deploy và Test thử
-
Nhấn nút Save and deploy ở góc phải màn hình.
-
Cloudflare sẽ cấp cho bạn một URL dạng:
https://my-api-proxy.<your-subdomain>.workers.dev. -
Mở Postman hoặc Browser và test thử: Gọi đến
https://my-api-proxy.<your-subdomain>.workers.dev/users/1 -
Nếu kết quả trả về thông tin User (giống hệt khi gọi
https://jsonplaceholder.typicode.com/users/1), thì chúc mừng bạn đã cấu hình Proxy thành công!
4. Mở rộng: Ẩn API Key an toàn
Nếu bạn gọi đến một dịch vụ yêu cầu API Key (ví dụ: OpenAI, Thời tiết, v.v.), hãy làm như sau để bảo mật:
-
Vào phần Settings của Worker > tab Variables.
-
Thêm một biến (Environment Variable), ví dụ tên là
API_TOKEN, nhập giá trị key của bạn vào và nhấn Save (có thể chọn Encrypt để bảo mật). -
Trong code Worker, chèn token này vào request trước khi gửi đi:
// Sử dụng env.API_TOKEN để lấy giá trị biến môi trường
modifiedRequest.headers.set("Authorization", `Bearer ${env.API_TOKEN}`);Như vậy, Client gọi đến Proxy hoàn toàn không biết API Key thực sự là gì.
Tổng kết
Việc sử dụng Cloudflare Workers làm Proxy không chỉ giúp giải quyết triệt để lỗi CORS ở Front-end mà còn là một best-practice tuyệt vời để che giấu các thông tin nhạy cảm. Với mức miễn phí lên tới 100.000 requests/ngày, đây là công cụ không thể thiếu trong bộ kỹ năng của các lập trình viên Web.








