Failing to load javascript module due to CORS

Hi there,
I load a page from localhost:1313. The page loads a javascript module

<script async type="module" src="http://localhost:8888/js/main.js"></script>

The file main.js is meant to be hosted by netlify. In my dev environment, I am serving by netlify dev.

My netlify.toml includes:

[[headers]]
  for = "/js/*"
  [headers.values]
    Access-Control-Allow-Origin = "http://localhost:1313"

However, my script still fails to load, with error “missing Access-Control-Allow-Origin”.

I have also tried to set Access-Control-Allow-Origin = "*", and adding crossorigin="anonymous" to the script tag, but still getting the error.

This is my dev environment, but have not been more successful in the staging environment.

So essentially, I don’t succeed to make cors work, and ideally I’d like a solution to work in all environments. Any guidance would help.

I’d try using relative URLs wherever possible to load files to avoid these CORS problems without messing with the headers. If I’m not wrong, localhost:1313 is Hugo’s default port, so in Hugo you might use something like {{ .RelPermalink}} to load the files.

@vdan In addition to what @hrishikesh says, if you are looking to one day publish your site on Netlify, you will need to use HTTPS sources instead of HTTP. That is, not only will localhost assets be unavailable on your published site, but you will get warnings and failures to load HTTP assets once your site has an SSL certificate. Make certain that the {{ .RelPermalink }} variable fixes each of these issues.

While @gregraven is right, I think @vdan might not run in that problem. Hugo has 2 variables, {{ .Permalink }} and {{ .RelPermalink }}. As I said above, the latter will always keep the URLs relative, but the former renders the absolute link based on baseURL configured in Hugo’s config (or as specified in the build command). So, if he has configured the baseURL with HTTPS, he would be fine and also, if he uses asset optimization from Netlify, the URLs would anyways turn to absolute.

But then again, if he has hardcoded the values like localhost:8888, what Greg said would be a dreadful reality.

Thanks to both of you for the prompt replies.

You are right the site running on localhost:1313 is a hugo site.

HTTPS for non-local environment is already embarked (e.g. staging environment will have https://staging--my-site.netlify.app/js/main.js as src value).

But in any case, the url will be absolute because the page loading the script is not hosted on netlify, i.e. I am willing to load a javascript module hosted on netlify, from a page (built by hugo) not hosted on netlify. So {{ .RelPermalink}} will not help here.

It seems the issue I am facing is my [[headers]] directive from netlify.toml is completely ignored:

  • for the case described above, no Access-Control-Allow-Origin is sent/received
  • if I attempt to load the file as a regular javascript, i.e. without the type=module, it does load, whatever the value I put to Access-Control-Allow-Origin in netlify.toml!

Well, can you try if Access-Control-Allow-Origin: * helps then? It’s just to make sure it’s Netlify that’s not sending the headers and not the problem on receiving end somehow.

I have setup a very minimalist project to demonstrate my issue:

~
+- site1
|     +-- index.html
+- site2
      +-- main.js
      +-- netlify.toml

index.html:

    <!doctype html>
    <html>
    <head>
    <script type="module" src="http://localhost:8888/main.js"></script>
    </head>
    <body></body>
    </html>

main.js

    console.log("hi");

netlify.toml

    [build]
      command = "echo 'running'"
      publish = "."
    
    [[headers]]
      for = "*"
      [headers.values]
         Access-Control-Allow-Origin = "http://localhost:1313" # I have also tried "*"

Running two servers:

  • one serving site1 on port 1313
  • one serving site2 on port 8888 (via netlify dev CLI)

Opening localhost:1313/ in the browser, still getting the missing Access-Control-Allow-Origin message.
Clearly, I must be missing something since this is very minimalist, yet not working…

I have also tried the wildcard for Access-Control-Allow-Origin. This is not working either.

From the network panel of the browser, I see that main.js is served, but with no Access-Control-Allow-Origin indeed.

Accept
	*/*
Accept-Encoding
	gzip, deflate
Accept-Language
	fr-FR,fr;q=0.8,en-US;q=0.5,en;q=0.3
Cache-Control
	no-cache
Connection
	keep-alive
DNT
	1
Host
	localhost:8888
Origin
	http://localhost:1313
Pragma
	no-cache
Referer
	http://localhost:1313/
User-Agent
	Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0

The setup does look pretty basic and seems about right. Would it be possible for you to ship this to production and check? There might be a chance that this is a problem with Netlify CLI. An alternative would be to try a different version of the package.

It does work in production. I have setup a basic public demonstration of different CORS cases at https://cors-example.netlify.app/.
So something is getting wrong with the Netlify CLI indeed.
Thank you.

hmm, that is frustrating.

Could you check the issues here:

and see if there is anything that covers what you are seeing? if not, would you please file a new issue? many thanks.