cors.js
· 3.1 KiB · JavaScript
Raw
// We support the GET, POST, HEAD, and OPTIONS methods from any origin,
// and allow any header on requests. These headers must be present
// on all responses to all CORS preflight requests. In practice, this means
// all responses to OPTIONS requests.
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS",
"Access-Control-Max-Age": "86400",
}
// The URL for the remote third party API you want to fetch from
// but does not implement CORS
const API_URL = "/cdn/cors.json"
// The endpoint you want the CORS reverse proxy to be on
const PROXY_ENDPOINT = "/"
async function handleRequest(request) {
const url = new URL(request.url)
let apiUrl = url.pathname;
if (apiUrl == null) {
apiUrl = API_URL
}
apiUrl = "https://p.alyssadev.xyz/file/ads-share" + apiUrl;
// Rewrite request to point to API url. This also makes the request mutable
// so we can add the correct Origin header to make the API server think
// that this request isn't cross-site.
request = new Request(apiUrl, request)
request.headers.set("Origin", new URL(apiUrl).origin)
let response = await fetch(request)
// Recreate the response so we can modify the headers
response = new Response(response.body, response)
// Set CORS headers
response.headers.set("Access-Control-Allow-Origin", "*")
// Append to/Add Vary header so browser will cache response correctly
response.headers.append("Vary", "Origin")
return response
}
function handleOptions(request) {
// Make sure the necessary headers are present
// for this to be a valid pre-flight request
let headers = request.headers;
if (
headers.get("Origin") !== null &&
headers.get("Access-Control-Request-Method") !== null &&
headers.get("Access-Control-Request-Headers") !== null
){
// Handle CORS pre-flight request.
// If you want to check or reject the requested method + headers
// you can do that here.
let respHeaders = {
...corsHeaders,
// Allow all future content Request headers to go back to browser
// such as Authorization (Bearer) or X-Client-Name-Version
"Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers"),
}
return new Response(null, {
headers: respHeaders,
})
}
else {
// Handle standard OPTIONS request.
// If you want to allow other HTTP Methods, you can do that here.
return new Response(null, {
headers: {
Allow: "GET, HEAD, POST, OPTIONS",
},
})
}
}
addEventListener("fetch", event => {
const request = event.request
const url = new URL(request.url)
if(url.pathname.startsWith(PROXY_ENDPOINT)){
if (request.method === "OPTIONS") {
// Handle CORS preflight requests
event.respondWith(handleOptions(request))
}
else if(
request.method === "GET" ||
request.method === "HEAD" ||
request.method === "POST"
){
// Handle requests to the API server
event.respondWith(handleRequest(request))
}
else {
event.respondWith(
new Response(null, {
status: 405,
statusText: "Method Not Allowed",
}),
)
}
}
})
| 1 | // We support the GET, POST, HEAD, and OPTIONS methods from any origin, |
| 2 | // and allow any header on requests. These headers must be present |
| 3 | // on all responses to all CORS preflight requests. In practice, this means |
| 4 | // all responses to OPTIONS requests. |
| 5 | const corsHeaders = { |
| 6 | "Access-Control-Allow-Origin": "*", |
| 7 | "Access-Control-Allow-Methods": "GET,HEAD,POST,OPTIONS", |
| 8 | "Access-Control-Max-Age": "86400", |
| 9 | } |
| 10 | |
| 11 | // The URL for the remote third party API you want to fetch from |
| 12 | // but does not implement CORS |
| 13 | const API_URL = "/cdn/cors.json" |
| 14 | |
| 15 | // The endpoint you want the CORS reverse proxy to be on |
| 16 | const PROXY_ENDPOINT = "/" |
| 17 | |
| 18 | async function handleRequest(request) { |
| 19 | const url = new URL(request.url) |
| 20 | let apiUrl = url.pathname; |
| 21 | |
| 22 | if (apiUrl == null) { |
| 23 | apiUrl = API_URL |
| 24 | } |
| 25 | apiUrl = "https://p.alyssadev.xyz/file/ads-share" + apiUrl; |
| 26 | |
| 27 | // Rewrite request to point to API url. This also makes the request mutable |
| 28 | // so we can add the correct Origin header to make the API server think |
| 29 | // that this request isn't cross-site. |
| 30 | request = new Request(apiUrl, request) |
| 31 | request.headers.set("Origin", new URL(apiUrl).origin) |
| 32 | let response = await fetch(request) |
| 33 | |
| 34 | // Recreate the response so we can modify the headers |
| 35 | response = new Response(response.body, response) |
| 36 | |
| 37 | // Set CORS headers |
| 38 | response.headers.set("Access-Control-Allow-Origin", "*") |
| 39 | |
| 40 | // Append to/Add Vary header so browser will cache response correctly |
| 41 | response.headers.append("Vary", "Origin") |
| 42 | |
| 43 | return response |
| 44 | } |
| 45 | |
| 46 | function handleOptions(request) { |
| 47 | // Make sure the necessary headers are present |
| 48 | // for this to be a valid pre-flight request |
| 49 | let headers = request.headers; |
| 50 | if ( |
| 51 | headers.get("Origin") !== null && |
| 52 | headers.get("Access-Control-Request-Method") !== null && |
| 53 | headers.get("Access-Control-Request-Headers") !== null |
| 54 | ){ |
| 55 | // Handle CORS pre-flight request. |
| 56 | // If you want to check or reject the requested method + headers |
| 57 | // you can do that here. |
| 58 | let respHeaders = { |
| 59 | ...corsHeaders, |
| 60 | // Allow all future content Request headers to go back to browser |
| 61 | // such as Authorization (Bearer) or X-Client-Name-Version |
| 62 | "Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers"), |
| 63 | } |
| 64 | |
| 65 | return new Response(null, { |
| 66 | headers: respHeaders, |
| 67 | }) |
| 68 | } |
| 69 | else { |
| 70 | // Handle standard OPTIONS request. |
| 71 | // If you want to allow other HTTP Methods, you can do that here. |
| 72 | return new Response(null, { |
| 73 | headers: { |
| 74 | Allow: "GET, HEAD, POST, OPTIONS", |
| 75 | }, |
| 76 | }) |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | addEventListener("fetch", event => { |
| 81 | const request = event.request |
| 82 | const url = new URL(request.url) |
| 83 | if(url.pathname.startsWith(PROXY_ENDPOINT)){ |
| 84 | if (request.method === "OPTIONS") { |
| 85 | // Handle CORS preflight requests |
| 86 | event.respondWith(handleOptions(request)) |
| 87 | } |
| 88 | else if( |
| 89 | request.method === "GET" || |
| 90 | request.method === "HEAD" || |
| 91 | request.method === "POST" |
| 92 | ){ |
| 93 | // Handle requests to the API server |
| 94 | event.respondWith(handleRequest(request)) |
| 95 | } |
| 96 | else { |
| 97 | event.respondWith( |
| 98 | new Response(null, { |
| 99 | status: 405, |
| 100 | statusText: "Method Not Allowed", |
| 101 | }), |
| 102 | ) |
| 103 | } |
| 104 | } |
| 105 | }) |