I tried this one out today. Let me know if you see any errors.
addEventListener(‘fetch’, event => {
event.respondWith(handleRequest(event.request))
})
function dec2hex(dec) {
return (“0” + dec.toString(16)).substr(-2)
}
function generateNonce() {
const arr = new Uint8Array(12)
crypto.getRandomValues(arr)
const values = Array.from(arr, dec2hex)
return [
btoa(values.slice(0, 5).join(“”)).substr(0, 14),
btoa(values.slice(5).join(“”)),
].join(“/”)
}
/**
- Respond to the request
-
@param {Request} request
*/
async function handleRequest(request) {
const nonce = generateNonce()
let response = await fetch(request)
let imageResponse = await fetch(request)
let type = imageResponse.headers.get(“Content-Type”) || “”
if (!type.startsWith(“text/”)) {
// Not text. Don’t modify.
let newHeaders = new Headers(imageResponse.headers)
newHeaders.set(“Cache-Control”, “public, max-age=2678400, immutable”)
newHeaders.set(“CDN-Cache-Control”, “public, max-age=2678400, immutable”)
newHeaders.set(“x-BW-test”, “Non-text item - headers edited!”)
// newHeaders.set(“Permissions-Policy”, “interest-cohort=()”)
newHeaders.set(“Strict-Transport-Security”, “max-age=63072000; includeSubDomains; preload”)
newHeaders.set(“X-Frame-Options”, “SAMEORIGIN”)
newHeaders.set(“X-Content-Type-Options”, “nosniff”)
newHeaders.set(“Referrer-Policy”, “no-referrer, strict-origin-when-cross-origin”)
newHeaders.set(“Content-Security-Policy”, “default-src ‘strict-dynamic’ https://perfectlighthousescores.com”)
newHeaders.set(“Permissions-Policy”, “geolocation=(), microphone=(), battery=(), accelerometer=(), camera=(), gyroscope=(), magnetometer=(), payment=(), usb=(), interest-cohort=()”)
newHeaders.set(“cf-nonce-generator”, “HIT”)
newHeaders.set(“Expect-CT”, “enforce max-age=30 report-uri=Report URI: Welcome to report-uri.com”)
newHeaders.set(“Cross-Origin-Embedder-Policy”, “require-corp; report-to=default”)
newHeaders.set(“Cross-origin-opener-policy-report-only”, “same-origin; report-to=default”)
newHeaders.set(“cross-origin-resource-policy”, “same-origin”)
newHeaders.set(“Cross-Origin-Opener-Policy”, “same-origin”)
return new Response(imageResponse.body, {
status: imageResponse.status,
statusText: imageResponse.statusText,
headers: newHeaders
})
}
const html = (await response.text())
.replace(/DhcnhD3khTMePgXw/gi, nonce)
.replace(
‘src="https://ajax.cloudflare.com’,
nonce="${nonce}" src="https://ajax.cloudflare.com
)
.replace(
‘src="https://static.cloudflareinsights.com’,
nonce="${nonce}" src="https://static.cloudflareinsights.com
)
.replace(
‘cloudflare-static/email-decode.min.js"’,
cloudflare-static/email-decode.min.js" nonce="${nonce}"
)
let ttl = undefined
let cache = caches.default
let url = new URL(request.url)
let shouldCache = false
let jsStuff = false
let svgStuff = false
const filesRegex = /(..(ac3|avi|bmp|br|bz2|css|cue|dat|doc|docx|dts|eot|exe|flv|gif|gz|ico|img|iso|jpeg|jpg|js|json|map|mkv|mp3|mp4|mpeg|mpg|ogg|pdf|png|ppt|pptx|qt|rar|rm|svg|swf|tar|tgz|ttf|txt|wav|webp|webm|webmanifest|woff|woff2|xls|xlsx|xml|zip))$/
const jsRegex = /(..(js))$/
const svgRegex = /(.*.(svg))$/
if (url.pathname.match(filesRegex)) {
shouldCache = true
ttl = 31536000
}
if (url.pathname.match(jsRegex)) {
jsStuff = true
}
if (url.pathname.match(svgRegex)) {
svgStuff = true
}
let newHeaders = new Headers(response.headers)
newHeaders.set(“Cache-Control”, “public, max-age=0”)
// newHeaders.set(“Permissions-Policy”, “interest-cohort=()”)
newHeaders.set(“Strict-Transport-Security”, “max-age=63072000; includeSubDomains; preload”)
newHeaders.set(“X-Frame-Options”, “SAMEORIGIN”)
newHeaders.set(“X-Content-Type-Options”, “nosniff”)
newHeaders.set(“Referrer-Policy”, “no-referrer, strict-origin-when-cross-origin”)
newHeaders.set(“Content-Security-Policy”, “default-src ‘strict-dynamic’ https://perfectlighthousescores.com”)
newHeaders.set(“Permissions-Policy”, “geolocation=(), microphone=(), accelerometer=(), battery=(), camera=(), gyroscope=(), magnetometer=(), payment=(), usb=(), interest-cohort=()”)
newHeaders.set(“Expect-CT”, “enforce max-age=30 report-uri=Report URI: Welcome to report-uri.com”)
newHeaders.set(“Cross-Origin-Embedder-Policy”, “require-corp; report-to=default”)
newHeaders.set(“Cross-origin-opener-policy-report-only”, “same-origin; report-to=default”)
newHeaders.set(“cross-origin-resource-policy”, “same-origin”)
newHeaders.set(“Cross-Origin-Opener-Policy”, “same-origin”)
if (ttl) {
newHeaders.set(“Cache-Control”, “public, max-age=” + ttl + “, immutable”)
newHeaders.set(“CDN-Cache-Control”, “public, max-age=” + ttl + “, immutable”)
} else {
newHeaders.set(“Content-Security-Policy-Report-Only”, report-uri https://perfectlighthousescores.report-uri.com/r/d/csp/enforce; default-src 'strict-dynamic' https://perfectlighthousescores.com; connect-src 'self' https://perfectlighthousescores.com https://cloudflareinsights.com; base-uri 'self' https://perfectlighthousescores.com; frame-src 'self' https://perfectlighthousescores.com; frame-ancestors 'self' https://perfectlighthousescores.com; form-action 'self'; style-src 'self' https://perfectlighthousescores.com; style-src-attr 'self' https://perfectlighthousescores.com; img-src 'self' https://perfectlighthousescores.com; font-src 'self' https://perfectlighthousescores.com; script-src 'nonce-${nonce}' 'strict-dynamic' https: 'self'; script-src-elem 'self' https://perfectlighthousescores.com 'nonce-${nonce}'
)
newHeaders.set(“Report-To”, “{‘group’:‘default’,‘max_age’:31536000,‘endpoints’:[{‘url’:‘Report URI: Welcome to report-uri.com’:true}”)
newHeaders.set(“X-XSS-Protection”, “1”)
}
newHeaders.set(“cf-nonce-generator”, “HIT”)
if (jsStuff) {
newHeaders.set(“Content-Type”, “application/javascript; charset=utf-8”)
}
if (svgStuff) {
newHeaders.set(“Content-Type”, “image/svg+xml; charset=utf-8”)
}
return new Response(html, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
})
}