Skip to content

Instantly share code, notes, and snippets.

@estevecastells
Created July 31, 2024 21:30
Show Gist options
  • Save estevecastells/b048a29784a06bc478d73b3a4dd6a2ed to your computer and use it in GitHub Desktop.
Save estevecastells/b048a29784a06bc478d73b3a4dd6a2ed to your computer and use it in GitHub Desktop.
Reverse proxy + Redirect GSC Live Test explorer
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const url = new URL(request.url)
// Serve robots.txt file
if (url.pathname === '/robots.txt') {
return new Response('User-agent: *\nDisallow: ', {
headers: { 'Content-Type': 'text/plain' }
})
}
// Handle proxy requests
if (url.pathname === '/proxy') {
const targetUrlString = url.searchParams.get('url')
const device = url.searchParams.get('device')
const redirect = url.searchParams.get('redirect')
if (!targetUrlString) {
return new Response('Missing URL parameter', { status: 400 })
}
try {
// Resolve relative URLs against the current origin
const targetUrl = new URL(targetUrlString, url.origin)
// Check if redirect is true
if (redirect === 'true') {
return Response.redirect(targetUrl.toString(), 302)
}
// If redirect is false or not set, proceed with proxy logic
if (redirect === 'false' || !redirect) {
// Clone the original headers
const newHeaders = new Headers(request.headers)
// Set the appropriate user-agent based on the device parameter
switch(device) {
case 'desktop':
newHeaders.set('User-Agent', 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Chrome/116.0.0.0 Safari/537.36')
break;
case 'windows':
newHeaders.set('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36')
break;
case 'android':
newHeaders.set('User-Agent', 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36')
break;
case 'iphone':
newHeaders.set('User-Agent', 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/116.0.5845.118 Mobile/15E148 Safari/604.1')
break;
default:
// Default to smartphone Googlebot if device is not specified or is set to 'mobile'
newHeaders.set('User-Agent', 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)')
}
const response = await fetch(targetUrl.toString(), {
method: request.method,
headers: newHeaders,
body: request.body
})
// Check if the response is HTML
const contentType = response.headers.get('content-type')
if (contentType && contentType.includes('text/html')) {
// If it's HTML, modify the content
let content = await response.text()
content = rewriteUrls(content, targetUrl.toString())
// Create a new response with the modified content
const newResponse = new Response(content, {
status: response.status,
statusText: response.statusText,
headers: response.headers
})
// Add CORS headers
newResponse.headers.set('Access-Control-Allow-Origin', '*')
return newResponse
} else {
// If it's not HTML, return the original response
const newResponse = new Response(response.body, response)
// Add CORS headers
newResponse.headers.set('Access-Control-Allow-Origin', '*')
return newResponse
}
}
} catch (error) {
return new Response('Error fetching the requested URL: ' + error.message, { status: 500 })
}
}
// Return 404 for any other requests
return new Response('Not Found', { status: 404 })
}
function rewriteUrls(html, baseUrl) {
const baseUrlObj = new URL(baseUrl);
// Function to resolve a URL against the base URL
const resolveUrl = (url) => {
if (url.startsWith('//')) {
return baseUrlObj.protocol + url;
}
if (url.startsWith('/')) {
return baseUrlObj.origin + url;
}
if (!url.startsWith('http://') && !url.startsWith('https://') && !url.startsWith('data:')) {
return new URL(url, baseUrl).href;
}
return url;
};
// Rewrite URLs in various attributes
html = html.replace(/(?:href|src|content|srcset)=['"]([^'"]+)['"]/gi, (match, url) => {
const newUrl = resolveUrl(url);
return match.replace(url, newUrl);
});
// Rewrite URLs in inline styles
html = html.replace(/url\(['"]?(.+?)['"]?\)/gi, (match, url) => {
const newUrl = resolveUrl(url);
return `url("${newUrl}")`;
});
return html;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment