Skip to content

Instantly share code, notes, and snippets.

@KoolPal
Forked from brandomeniconi/cf-wp-cache-worker.js
Created April 21, 2020 12:39
Show Gist options
  • Save KoolPal/def7c1a9f0717f86d1a8af5ab273b2a2 to your computer and use it in GitHub Desktop.
Save KoolPal/def7c1a9f0717f86d1a8af5ab273b2a2 to your computer and use it in GitHub Desktop.
Basic Cloudflare Worker that allows efficient page caching for Wordpress websites
// Version 1.4
const DAY_IN_SECONDS = 60*60*24;
const BLACKLISTED_URL_PARAMS = [
'fbclid', // Google Ads click Id
'gclid', // Facebook click Id
'msclkid', // Micorosft Ads Click Id
];
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
})
async function fetchAndApply(request) {
let cloudflareOptions = {}
let url = new URL(request.url)
// Bypass Cache if is a non cachable WP request or is not a GET request
let bypassCache = isWordpressNoCache( request ) || (request.method !== 'GET');
if ( bypassCache ) {
// Disable page Cache, this shoud keep the static assets cache on.
cloudflareOptions.cacheEverything = false;
} else {
// Force request caching
cloudflareOptions.cacheEverything = true;
// Set Edge Cache default TTL
cloudflareOptions.cacheTtl = 365 * DAY_IN_SECONDS;
// Set thje edge cache TTL by response status
cloudflareOptions.cacheTtlByStatus = {
"200-299": 365 * DAY_IN_SECONDS,
404: 60 * DAY_IN_SECONDS,
"500-599": 100
};
//blacklisted url params
BLACKLISTED_URL_PARAMS.forEach((blParam) => {
url.searchParams.delete(blParam);
});
//or delete all URL parameters unconditionally
//url.search = '';
}
//create a new editable request
let newRequest = new Request(url.toString(), request );
// Pipe the request to the CF servers and wait for the response
let response = await fetch(newRequest, {cf : cloudflareOptions} );
// Copy the response so that we can modify headers.
response = new Response(response.body, response)
// Lower the browser max-age for pages to 1 mins. This is done to avoid caching a website page
// on user device for the entire edge cache TTL (default CF behavior). We can't purge or invalidate it!
if ( !bypassCache && !isStaticFile( response ) ) {
response.headers.set("Cache-Control", "max-age=60");
}
// return the response to client
return response
}
// Checks if we should not cache the request due to one of the following reasons:
// * user logged in
// * user is commenting a post
// * user has some products in cart or is using woocommerce
// * user is in the wp-admin section or other WP related resources
function isWordpressNoCache( request ) {
// Get full URL from the request
const url = new URL(request.url)
// Get raw cookies from the request
const cookie = request.headers.get('Cookie');
//Create a regex to match cookies that suggeest: user logged-in, comments or woocomerce session
const wpRegex = /;\s?(wordpress_logged_in_|comment_|woocommerce_)[^=]+=/g;
return (
// If request contains cookies check if there are WP related cookies
( cookie && cookie.match(wpRegex) )
// Check if the URL path is WP Core related
|| url.pathname.startsWith('/wp-')
// Check if the URL path is WP Core related (roots/bedrock version)
|| url.pathname.startsWith('/wp/wp-') );
}
// Check if a response is a static file or a document or API response
function isStaticFile( response ){
// Get content-type from the response
let contentType = response.headers.get('content-type');
// Check if the response content type is an HTML page or a JSON object
if ( contentType && ( contentType.startsWith('text/html') || contentType.startsWith('application/json') ) ) {
return false;
}
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment