Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS policy blocked Cloudfare Worker Function

I have cloudfare worker function, which I'm trying to call from my React web app, where I constantly have error

Access to fetch at 'https://xxxxx.workers.dev/' from origin 'http://localhost:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled

I don't want to use no-cors mode, and I'm trying to find option on cloudfare dashboard where to Allow-Origins domain, but it seems impossible to find. Please anyone idea how to solve this?

This is code of function

addEventListener("fetch", (event) => {
  event.respondWith(
    handleRequest(event.request).catch(
      (err) => new Response(err.stack, { status: 500 })
    )
  );
});

/**
 * Many more examples available at:
 *   https://developers.cloudflare.com/workers/examples
 * @param {Request} request
 * @returns {Promise<Response>}
 */
async function handleRequest(request) {
  const { pathname } = new URL(request.url);

  if (pathname.startsWith("/api")) {
    return new Response(JSON.stringify({ pathname }), {
      headers: { "Content-Type": "application/json" },
    });
  }

  if (pathname.startsWith("/status")) {
    const httpStatusCode = Number(pathname.split("/")[2]);

    return Number.isInteger(httpStatusCode)
      ? fetch("https://http.cat/" + httpStatusCode)
      : new Response("That's not a valid HTTP status code.");
  }

  return new Response({
      hello: "world",
    });
}
like image 344
HardRock Avatar asked Nov 18 '25 04:11

HardRock


2 Answers

This is what helped me to solve the issue: https://community.cloudflare.com/t/worker-site-http-request-to-worker/151529/8

Function code:

// An example worker which supports CORS. It passes GET and HEAD
// requests through to the origin, but answers OPTIONS and POST
// requests directly. POST requests must contain a JSON payload,
// which is simply echoed back.

addEventListener('fetch', event => {
  event.respondWith(handle(event.request)
    // For ease of debugging, we return exception stack
    // traces in response bodies. You are advised to
    // remove this .catch() in production.
    .catch(e => new Response(e.stack, {
      status: 500,
      statusText: "Internal Server Error"
    }))
  )
})

async function handle(request) {
  if (request.method === "OPTIONS") {
    return handleOptions(request)
  } else if (request.method === "POST") {
    return handlePost(request)
  } else if (request.method === "GET" || request.method == "HEAD") {
    // Pass-through to origin.
    return fetch(request)
  } else {
    return new Response(null, {
      status: 405,
      statusText: "Method Not Allowed",
    })
  }
}

// We support the GET, POST, HEAD, and OPTIONS methods from any origin,
// and accept the Content-Type header on requests. These headers must be
// present on all responses to all CORS requests. In practice, this means
// all responses to OPTIONS or POST requests.
const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type",
}

function handleOptions(request) {
  if (request.headers.get("Origin") !== null &&
    request.headers.get("Access-Control-Request-Method") !== null &&
    request.headers.get("Access-Control-Request-Headers") !== null) {
    // Handle CORS pre-flight request.
    return new Response(null, {
      headers: corsHeaders
    })
  } else {
    // Handle standard OPTIONS request.
    return new Response(null, {
      headers: {
        "Allow": "GET, HEAD, POST, OPTIONS",
      }
    })
  }
}

async function handlePost(request) {
  if (request.headers.get("Content-Type") !== "application/json") {
    return new Response(null, {
      status: 415,
      statusText: "Unsupported Media Type",
      headers: corsHeaders,
    })
  }

  // Detect parse failures by setting `json` to null.
  let json = await request.json().catch(e => null)
  if (json === null) {
    return new Response("JSON parse failure", {
      status: 400,
      statusText: "Bad Request",
      headers: corsHeaders,
    })
  }

  return new Response(JSON.stringify(json), {
    headers: {
      "Content-Type": "application/json",
      ...corsHeaders,
    }
  })
}

Make a call

const Http = new XMLHttpRequest();
    const url='HTTPS://YOUR_CLOUDFLARE_WORKER';
    Http.open("POST", url);
    Http.setRequestHeader('Accept', 'application/json');
    Http.setRequestHeader('Content-Type', 'application/json');
    Http.send('{"test": "GP"}');

    Http.onreadystatechange = (e) => {
      console.log(Http.responseText)
    }
like image 92
HardRock Avatar answered Nov 21 '25 10:11

HardRock


I did this:

export default {
  async fetch(request, env, ctx) {

    // Change this to what you want for CORS
    const corsHeaders = {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "POST",
      "Access-Control-Allow-Headers": 'Content-Type'
    };

    if (request.method === "OPTIONS") {
      // Handle CORS preflight requests
      return new Response(null, {
        headers: {...corsHeaders}
      })
    }

    // YOUR CODE HERE

    return new Response(email, {
        headers: {
          ...corsHeaders,
        },
      });
    }
like image 25
funerr Avatar answered Nov 21 '25 09:11

funerr