This is the index.js code for a CloudFlare worker to proxy RudderStack's JS SDK and Requests to make them Ad-Blocker Proof
This file contains 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
addEventListener('fetch', event => { | |
if(event.request.method === 'OPTIONS'){ | |
event.respondWith(handleOptions(event.request)) | |
}else{ | |
event.respondWith(handleRequest(event.request)) | |
} | |
}) | |
const corsHeaders = { | |
"Access-Control-Allow-Origin": "*", | |
"Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS", | |
"Access-Control-Max-Age": "86400", | |
} | |
function handleOptions(request){ | |
let headers = request.headers; | |
if ( | |
headers.get("Origin") !== null && | |
headers.get("Access-Control-Request-Method") !== null && | |
headers.get("Access-Control-Request-Headers") !== null | |
){ | |
let respHeaders = { | |
...corsHeaders, | |
"Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers"), | |
} | |
return new Response(null, {headers: respHeaders}); | |
}else{ | |
return new Response(null, {headers: {Allow: "GET, HEAD, POST, OPTIONS"}}) | |
} | |
} | |
async function handleRequest(request) { | |
const { pathname, origin } = new URL(request.url); | |
const DATA_PLANE_URL = 'https://obsessivealnoa.dataplane.rudderstack.com'; | |
const RUDDER_METHODS = ['page', 'identify', 'group', 'track', 'alias']; | |
const RUDDER_SDK_URL = 'https://cdn.rudderlabs.com/v1/rudder-analytics.min.js'; | |
const RUDDER_SOURCE_CONFIG_URL = 'https://api.rudderlabs.com/sourceConfig'; | |
if ( pathname === '/sourceConfig/'){ | |
request = new Request(RUDDER_SOURCE_CONFIG_URL, request) | |
request.headers.set("Origin", origin) | |
let response = await fetch(request) | |
response = new Response(response.body, response); | |
response.headers.set("Access-Control-Allow-Origin", '*'); | |
response.headers.append("Vary", "Origin"); | |
return response; | |
} else if ( pathname === '/dataPlane' ){ | |
const init = {headers: {'Content-Type': 'application/javascript'}}; | |
const response = await fetch(RUDDER_SDK_URL, {headers: request.headers}); | |
const responseText = await response.text(); | |
return new Response(responseText, init); | |
}else{ | |
const fragments = pathname.split('/'); | |
/** | |
* this is to catch the actual rudder calls which will be in format | |
* /v1/page | |
* /v1/track | |
* etc. | |
* Splitting on '/' will give us ['','v1','page'] for instance | |
* Rudder request will also be POST requests | |
* Time to filter out bad requests | |
*/ | |
if (request.method !== 'POST' || !RUDDER_METHODS.includes(fragments[2])){ | |
return new Response(null, {status: 500}); | |
}else{ | |
return fetch( | |
`${DATA_PLANE_URL}${pathname}`, | |
{ | |
method: 'POST', | |
headers: request.headers, | |
body: request.body | |
} | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment