2

So i started to get my hands dirty with cloudflare pages and workers

My thought is

  1. get a domain mydomain.com (done)
  2. make a static site @ github myaccount.github.io (done)
  3. make a cloudflare pages page add CNAME to DNS ZONE (done) so myaccount.github.io can be @ my-official-site.com (done)
  4. make a cloudflare worker https://myworker.myclaccount.workers.dev (done)

So when i request my-official-site.com i get the content of myaccount.github.io


Now i want to run from my myaccount.github.io a worker to get some html or json or....

  1. I trying to fetch from my myaccount.github.io (index.html)
<script>
fetch('https://myworker.myclaccount.workers.dev')
  .then(response => response.json())
  .then(data => console.log(data));
</script>
  1. I get the request to my worker like this
const html = 
  "<p>This markup was generated by a Cloudflare Worker.</p>"

async function handleRequest(request) {
  return new Response(html, {
    headers: {
      "content-type": "text/html;charset=UTF-8",
    },
  })
}

addEventListener("fetch", event => {
  return event.respondWith(handleRequest(event.request))
})

The problem is

Access to fetch at 'https://myworker.myclaccount.workers.dev/' 
from origin 'my-official-site.com' has been blocked by CORS policy: 
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 create a

_headers.txt (https://developers.cloudflare.com/pages/platform/headers) at the root of my github "site" with this

/*
  Access-Control-Allow-Origin: *

but the same...

I'm new to serverless and jamstack (i now js, css, html) but new to this concept

knowledge (android, c#, php, wp, unity, some node.js)

Thank you for your help.

ffflabs
  • 17,166
  • 5
  • 51
  • 77
LightsOn
  • 43
  • 4

3 Answers3

2

At the top of the Cloudflare documentation, it states

Custom headers defined in the _headers file are not currently applied to responses from Functions

I believe this is the issue you are encountering. You need to apply the headers directly in your worker function, as specified here -

https://developers.cloudflare.com/pages/how-to/add-custom-http-headers

On a side note, I'd recommend updating your question title to reflect what is being asked.

David
  • 1,007
  • 7
  • 14
0

You don't seem to be using Cloudflare Pages. Such deploy would for the most part replace your current Github Pages + Cloudflare Workers combo, and you wouldn't deal with cross-site requests for the use case you've shown.

Even if you mean to keep using workers as a separate augmentation tool, enabling CORS in your current setup is missing the point. Workers can be transparently mounted on any route of your domain, therefore turning cross-site requests into same-origin even if the real servers are half a planet away.


Anyway, there are for sure several use cases for CORS in workers. For a basic example, here's a simple middleware that takes a Response or a promise of one, returning a copy with modified headers. (There's a lot more to CORS, but that's out of this question's scope)

/**
 * @param {Response|Promise<Response>} res
 * @returns {Promise<Response>}
 */
async function corsEnabler(res) {
   res = await res 
   const corsResponse = new Response(res.body, res)
   corsResponse.headers.set('Access-Control-Allow-Origin','*')
   corsResponse.headers.set('Access-Control-Allow-Methods','GET,POST,HEAD,OPTIONS')
   return corsResponse
}

(I'm awaiting res in case I'm passed the promise of a response. But this doesn't mean awaiting for its contents!) Then, where your code says

addEventListener("fetch", event => {
   return event.respondWith(
         handleRequest(event.request)
   )
})

You would use the middleware like

addEventListener("fetch", event => {
   return event.respondWith(
        corsEnabler( handleRequest(event.request) )
   )
})

If you were using module syntax you would use a default export instead of a FetchEvent

export default {
  fetch(request, env, context) {
    return corsEnabler( handleRequest(request) )
  }
}

And if you used page functions:

export async function onRequest(context) {
   return corsEnabler( handleRequest(context.request) )
}
ffflabs
  • 17,166
  • 5
  • 51
  • 77
0

You can use Cloudflare Bulk Trasform rules to edit response headers and add one or more specific allowed domains to the CORS headers field returning to clients (in this case to your worker).

Free plans users can set up to 5 rules while in a single rule you can set multiple request or response headers.

fab23
  • 59
  • 8