Skip to content

Commit cb69c4f

Browse files
Merge pull request #182 from richardthe3rd/claude/fix-cloudflare-data-feed-UEoy2
Fix data feed failing on Cloudflare preview
2 parents 4c8c62f + 0a72eff commit cb69c4f

1 file changed

Lines changed: 28 additions & 4 deletions

File tree

cloudflare-worker/worker.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
/**
22
* Cloudflare Worker - CORS Proxy for Cambridge Beer Festival Data API
3-
*
3+
*
44
* This worker proxies requests to data.cambridgebeerfestival.com and adds
55
* the necessary CORS headers to allow the web app to access the data.
6-
*
6+
*
77
* It also serves the festivals.json file which contains festival metadata
88
* and enables dynamic loading of festival drinks.
9+
*
10+
* Cache Strategy:
11+
* - Uses Vary: Origin header to ensure CORS responses are cached per origin
12+
* - CORS preflight cache (Access-Control-Max-Age) is reduced to 10 seconds for
13+
* staging/preview environments for quick recovery from deployment issues
914
*/
1015

1116
// Import festivals data directly - copied from data/festivals.json during build
@@ -81,7 +86,7 @@ export default {
8186
// Clone the response and add CORS headers
8287
const newHeaders = new Headers(response.headers);
8388
setCorsHeaders(newHeaders, request);
84-
89+
8590
// Ensure JSON responses explicitly declare UTF-8 encoding
8691
// This prevents mojibake when non-ASCII characters (é, ö, ä, ñ) are present
8792
const contentType = newHeaders.get('Content-Type');
@@ -200,13 +205,28 @@ function parseDirectoryListingForBeverageTypes(html) {
200205
}
201206

202207
function handleCorsPreflight(request) {
208+
const origin = request.headers.get('Origin') || '';
209+
210+
// Set shorter CORS preflight cache for staging/preview environments
211+
// to prevent stale CORS responses after deployments
212+
let maxAge = '300'; // 5 minutes for production
213+
214+
if (origin.endsWith('.staging-cambeerfestival.pages.dev') ||
215+
origin.endsWith('.cambeerfestival.pages.dev') ||
216+
origin === 'https://staging.cambeerfestival.app' ||
217+
origin.endsWith('.trycloudflare.com') ||
218+
origin.startsWith('http://localhost') ||
219+
origin.startsWith('http://127.0.0.1')) {
220+
maxAge = '10'; // 10 seconds for development/staging
221+
}
222+
203223
return new Response(null, {
204224
status: 204,
205225
headers: {
206226
...getCorsHeaders(request),
207227
'Access-Control-Allow-Methods': 'GET, OPTIONS',
208228
'Access-Control-Allow-Headers': 'Content-Type',
209-
'Access-Control-Max-Age': '300', // 5 minutes - allows quick recovery from CORS issues
229+
'Access-Control-Max-Age': maxAge,
210230
},
211231
});
212232
}
@@ -219,6 +239,7 @@ function getCorsHeaders(request) {
219239
return {
220240
'Access-Control-Allow-Origin': origin,
221241
'Access-Control-Allow-Credentials': 'true',
242+
'Vary': 'Origin', // Tell caches to key by Origin header
222243
};
223244
}
224245

@@ -231,6 +252,7 @@ function getCorsHeaders(request) {
231252
return {
232253
'Access-Control-Allow-Origin': origin,
233254
'Access-Control-Allow-Credentials': 'true',
255+
'Vary': 'Origin', // Tell caches to key by Origin header
234256
};
235257
}
236258

@@ -241,6 +263,7 @@ function getCorsHeaders(request) {
241263
return {
242264
'Access-Control-Allow-Origin': origin,
243265
'Access-Control-Allow-Credentials': 'true',
266+
'Vary': 'Origin', // Tell caches to key by Origin header
244267
};
245268
}
246269

@@ -252,6 +275,7 @@ function getCorsHeaders(request) {
252275
return {
253276
'Access-Control-Allow-Origin': origin,
254277
'Access-Control-Allow-Credentials': 'true',
278+
'Vary': 'Origin', // Tell caches to key by Origin header
255279
};
256280
}
257281

0 commit comments

Comments
 (0)