-1

I am using the following code to serve a HTML file.

func main() {
    http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
        path := r.URL.Path
        if path == "/" {
            path = "index.html"
        }

        http.ServeFile(rw, r, "./"+path)
    })

    http.ListenAndServe(":5555", nil)
}

This HTML file includes a JavaScript file that uses fetch to retrieve some data. This works fine when serving through apache, but not when served through the Go-server.

This is the fetch-request:

const fetchSettings = {
        method: "POST",
        body: JSON.stringify(requestBody),
        headers: {
            "Content-Type": "application/json",
        }
    };
const response = await fetch("https://some.url", fetchSettings);

And here is the error I'm getting:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://some.url. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://some.url. (Reason: CORS request did not succeed).
  • What is the error you're getting on the html page? If you open the devtools console, we'll have more context on what's going wrong. – Jay K. Jul 09 '21 at 21:13
  • 1
    It is probably failing because of CORS errors. You can add handling for OPTIONS in your handler to make it work – Burak Serdar Jul 09 '21 at 21:15
  • @JayK. Sorry, I edited to add it – jazzdrottningen Jul 09 '21 at 21:16
  • 2
    The error tells you exactly what the problem is. To fix it, first understand CORS by [reading this](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). Then [check this issue with quite a few options for solutions](https://stackoverflow.com/questions/22972066/how-to-handle-preflight-cors-requests-on-a-go-server). – Dean Jul 09 '21 at 21:21
  • @Dean Thank you, but unless I'm misunderstanding something all of those solutions are reliant on me controlling the server the request is being sent to, which isnt the case here. Please let me know if I'm understanding the answers to the question you linked incorrectly. – jazzdrottningen Jul 09 '21 at 21:31
  • 1
    Yes, they do rely on you controlling the server handling the request. They're a security measure. When you say "I am using the following code to serve a HTML file", that sounds like you do in fact control the server. If you don't, then CORS is protecting users accessing that server from potentially unsafe cross-origin requests, and you won't be able to get around that. – Adrian Jul 09 '21 at 21:39
  • @Adrian Thank you, why does it work when the html file is served through apache locally on my computer but not when it's served through the go executable then? – jazzdrottningen Jul 09 '21 at 21:42
  • 2
    @jazzdrottningen Are your go app and Apache server both serving from the exact same URL? Because it sounds likely that whatever URL the Apache server is being served at is on the list of allowed origins for the remote servers' CORS configuration. So let's say you are hitting https://localhost:apache/ and CORS on remote server is set up to allow cross origin from that url, it would work fine. But when you run it from http://localhost:1234/ it fails. Regardless, this is a CORS issue (it's working as intended), not a go problem. – Dean Jul 09 '21 at 22:46
  • @Dean Thank you! It was indeed the port the go server was running on that was the issue. – jazzdrottningen Jul 09 '21 at 22:52

1 Answers1

1

You need to include an Access-Control-Allow-Origin header:

rw.Header().Set("Access-Control-Allow-Origin", "*")

That one allows all origins, you can read more here: https://perennialsky.medium.com/handle-cors-in-golang-7c5c3902dc08

Here is how it would fit in your code:

func main() {
    http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
        path := r.URL.Path
        if path == "/" {
            path = "index.html"
        }
        rw.Header().Set("Access-Control-Allow-Origin", "*")
        http.ServeFile(rw, r, "./"+path)
    })
    
    http.ListenAndServe(":5555", nil)
}
AbsentBird
  • 321
  • 1
  • 8
  • Thanks, but I already tried that and it makes no difference. – jazzdrottningen Jul 09 '21 at 21:40
  • Why would it say "Reason: CORS header ‘Access-Control-Allow-Origin’ missing" if the header was set? Are you sure it's being set correctly? – AbsentBird Jul 09 '21 at 21:42
  • The reason it makes no difference is that the fetch-request isn't being sent to the go server, but to a different web server that I have no control over. – jazzdrottningen Jul 09 '21 at 21:44
  • You said that it works fine when the script is being hosted by Apache, that shouldn't have any effect on the remote server, but it could change the CORS policy of the script itself. You cannot access the remote server without setting the CORS header locally. – AbsentBird Jul 09 '21 at 22:14