Last active 1626874058

cors proxy cloudflare worker

Revision ad8ea40083b00458c7043b5602ab4023763e3aa9

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