HTTP endpoint error on POST application/json for browser extension

I am building a browser extension that should communicate with my webapp server, and I am trying to set up a HTTP endpoint on the anvil server like this:

@anvil.server.http_endpoint('/data', methods=['POST'], enable_cors=True)
def write_data():
  print(anvil.server.request.body_json)
  return {'status': 'ok'}

On client side (Chrome web extension, testing from browser console):

fetch(
  api_url + '/data', 
  {method: 'POST', body: '[123]', headers: {'Content-Type': 'application/json'}}
)

where api_url is the private URL to my Anvil app.

And I get back this error:

Access to fetch at ‘https://<app_id>.anvil.app/_/private_api/<access_key>/data’ from origin ‘chrome-extension://fnamlmhlgobjeofgfklfbbkibhfbpmpl’ has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

The same request works from reqbin.com and curl.

It also works if I don’t specify content-type header:

fetch(
  api_url + '/data', 
  {method: 'POST', body: '[123]'}
)

Then as expected in anvil.server.body I have anvil._serialise.StreamingMedia object, and anvil.server.body_json is None.

I can send plain text and decode raw bytes, but it would be nicer if application/json type worked in this instance.

Hi @aia,

Welcome to the forum!

You can provide the required access-control-allow-headers option by adding an 'OPTIONS' method to your http endpoint:

@anvil.server.http_endpoint('/data', methods=['POST', 'OPTIONS'], enable_cors=True)
def write_data():
  if anvil.server.request.method == 'OPTIONS':
    r = anvil.server.HttpResponse()
    r.headers['access-control-allow-headers'] = 'Content-Type'
    return r
  print(anvil.server.request.body_json)
  return {'status': 'ok'}
1 Like

Thank you, @bridget, this worked!

1 Like

It might be worth mentioning here for anyone new to dealing with CORS issues that the OPTIONS method is required for the “preflight” request made :

Caught me out a few times and is not immediately obvious, in my opinion anyway.

2 Likes