21

I'm am trying to fetch a serverless function from a react app in development mode with the following code.

let response = await fetch(url,
       {
           method: 'POST',
           mode: 'cors',
           body: "param=" + paramVar,
        })
        .then(response => response.json());

The backend function is a Python Cloud function with the following code:

def main(request):
    # CORS handling
    if request.method == 'OPTIONS':
        # Allows GET requests from any origin with the Content-Type
        # header and caches preflight response for an 3600s
        headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET, POST',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Max-Age': '3600'
        }

        return ('', 204, headers)
    
    # Set CORS headers for the main request
    headers = {
        'Content-Type':'application/json',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': 'Content-Type',
    }

    # Process request
    return (json.dumps(response), 200, headers)

But I keep getting the following error:

Access to fetch at 'url' from origin 'http://localhost:3000' 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.

When I try to perform the same request using curl I get a proper response. Using curl to get the options gives me the following:

HTTP/2 204
access-control-allow-headers: Content-Type
access-control-allow-methods: GET, POST
access-control-allow-origin: *
access-control-max-age: 3600
content-type: text/html; charset=utf-8
date: Sun, 16 Aug 2020 01:29:41 GMT

Anyone can help me understand why I'm not able to get a response at my front-end? The 'Access-Control-Allow-Origin' is present in the headers so I really don't understand what is the cause of this error.

lspinheiro
  • 423
  • 1
  • 4
  • 9
  • `Should allow OPTIONS method` - doesn't the code do that @charlietfl ... `if request.method == 'OPTIONS'` – Jaromanda X Aug 16 '20 at 02:39
  • This issue can occur due to different causes. Take a look at this [answer](https://stackoverflow.com/a/43881141/11928130), it may help you troubleshooting your issue. – tzovourn Aug 21 '20 at 15:39

4 Answers4

2

Install the CORS package in the backend. Then open your server.js file or whatever is yours. Then import it to the file

const cors = require('cors');

And then use it

app.use(cors());

reload the browser and should be done!

0

add content-type header to your fetch method in the frontend and try again:

let response = await fetch(url,
       {
           method: 'POST',
           mode: 'cors',
           body: "param=" + paramVar,
           headers: {
             'Content-Type': 'application/json'
       },
  }).then(response => response.json());
Methkal Khalawi
  • 2,368
  • 1
  • 8
  • 13
0

This is my first post at Stack

I saw OP's response and I think I know what they meant - as I ran into the same problem myself.

Basically when you send a request to 'url', if that URL didn't reply with a successful response, then it will send you a 'bad response', in my case, a "503". A "503" response is still a response, but this response would not contain the access-control-allow-origin header, so the browser (dutifully) replied that it will not accept this - even if it's garbage anyway!

Hope that might be helpful to someone else ... Cheers

Rayftw192
  • 9
  • 1
-1

There was actually a bug in the backend that was only triggered by some additional headers added by the browser. In that particular case, the server was returning a 404 error which wouldn't contain my header definitions and would cause the CORS policy block.

I was only able to identify the bug after I used devtools to track the request sent by the browser and replicated all the headers in my curl request. After fixing the function logic the problem was fixed.

lspinheiro
  • 423
  • 1
  • 4
  • 9