Created
February 16, 2026 06:28
-
-
Save teklynk/778cafd7f08bb03d8df64d066a1b01f7 to your computer and use it in GitHub Desktop.
Cloudflare serverless worker: Failover to secondary server if main server is down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export default { | |
| async fetch(request) { | |
| const primaryUrl = 'https://api.example.com'; | |
| const fallbackUrl = 'https://api2.example.com'; | |
| const url = new URL(request.url); | |
| const path = url.pathname + url.search; | |
| // Define CORS headers | |
| const corsHeaders = { | |
| 'Access-Control-Allow-Origin': '*', | |
| 'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS', | |
| 'Access-Control-Allow-Headers': 'Content-Type', | |
| }; | |
| // Handle OPTIONS preflight requests | |
| if (request.method === 'OPTIONS') { | |
| return new Response(null, { | |
| headers: corsHeaders | |
| }); | |
| } | |
| // Helper function to add CORS headers to a response | |
| const addCors = (response) => { | |
| // Recreate the response to modify headers (original might be immutable) | |
| const newResponse = new Response(response.body, response); | |
| Object.keys(corsHeaders).forEach(key => { | |
| newResponse.headers.set(key, corsHeaders[key]); | |
| }); | |
| return newResponse; | |
| }; | |
| // Helper function to handle the fetch logic | |
| async function fetchUpstream(targetUrl) { | |
| const response = await fetch(targetUrl + path, request); | |
| // If origin responds with a redirect (301/302), return it with CORS headers | |
| if ([301, 302].includes(response.status)) { | |
| return new Response(null, { | |
| status: response.status, | |
| headers: { | |
| 'Location': response.headers.get('Location'), | |
| ...corsHeaders | |
| } | |
| }); | |
| } | |
| return response; | |
| } | |
| // Try primary | |
| try { | |
| const response = await fetchUpstream(primaryUrl); | |
| if (response.ok) { | |
| return addCors(response); | |
| } | |
| } catch (e) { | |
| console.error('Primary failed:', e); | |
| } | |
| // Fallback: try the same logic on secondary | |
| try { | |
| const response = await fetchUpstream(fallbackUrl); | |
| // Return the response (even if it's an error like 404) with CORS headers | |
| return addCors(response); | |
| } catch (e) { | |
| console.error('Fallback failed:', e); | |
| } | |
| return new Response('Service unavailable', { | |
| status: 503, | |
| headers: corsHeaders | |
| }); | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment