No 'Access-Control-Allow-Origin' header is present error from JS

I have an edge function in Javascript on Cloudflare Workers. The only thing it does is to check a specific header and return a JSON containing a value accordingly

See code below

async function handleRequest(request) {

  const url = new URL(request.url);

  const psk_db = await KV_STORAGE.get(request.headers.get(PRESHARED_AUTH_HEADER_KEY));

  if (psk_db === null) {
    return new Response("Access denied", { status: 404 });
    //calculate number

    //return JSON
    const data = {
      pswd: psk_db,

    json = JSON.stringify(data, null, 2);

  return new Response(json, {
      headers: {
        'content-type': 'application/json;charset=UTF-8',
        'Access-Control-Allow-Origin': url.origin,


addEventListener('fetch', event => {

Now, the function works fine on the Cloudflare test envirovment but when I try to request from an html page with a button that run this javascript function

function RequestCode() {
  const Http = new XMLHttpRequest();
  const url = "";"GET", url);
  Http.setRequestHeader("Access-Control-Allow-Origin", "*");
  Http.setRequestHeader("X-Custom-PSK", "m_custom_key");

  Http.onreadystatechange = (e) => {

I got the error

Access to XMLHttpRequest at ‘my_workers_url’ from origin ‘null’ 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.

I have added on both side the Access-Control-Allow-Origin at * but it doesn’t work

What can I do to avoid the error?

Are you returning the right headers in response to OPTIONS requests?

Probably not as I’m not managing the OPTIONS requests.

I have tried Python with the smile code and everything worked.

import requests
url = my_url
r=requests.get(url, headers=my_headers)

How can I add the right headers without having other OPTIONS requests going on?

You can’t since browsers make OPTIONS preflight requests and if the header isn’t present on the OPTIONS then it’ll never make the “actual” GET request.

gotcha! and is there some kind of documentation/tutorial on how do that as I’m pretty new to the OPTIONS requests

The issue was that the worker didn’t answer to OPTIONS request.

The solution was to handle these type of requests with

if (request.method === "OPTIONS") {
    return handleOptions(request)


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, OPTIONS",


const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Methods": "GET, OPTIONS",
  "Access-Control-Allow-Headers": "*",

Clearly Access-Control-Allow-Origin and Access-Control-Allow-Headers adding only the

Reference Handling preflight requests - #3 by webchad

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.