Python Falcon CORS Error with AJAX

Question:

I’ve read multiple SO questions on this error, but none of them seem to be helping me resolve this issue. The Falcon server isn’t even printing out the print statements of the on_post method (on_get is working fine for some reason), not sure what’s wrong with my on_post method.


I’m calling a post method from my localhost:8000 as such:

#client side
var ax = axios.create({
    baseURL: 'http://localhost:5000/api/',
    timeout: 2000,
    headers: {}
});

ax.post('/contacts', {
    firstName: 'Kelly',
    lastName: 'Rowland',
    zipCode: '88293'
}).then(function(data) {
    console.log(data.data);
}).catch(function(err){
    console.log('This is the catch statement');
});

This is the Falcon server code

import falcon
from peewee import *


#declare resources and instantiate it
class ContactsResource(object):
    def on_get(self, req, res):
        res.status = falcon.HTTP_200
        res.body = ('This is me, Falcon, serving a resource HEY ALL!')
        res.set_header('Access-Control-Allow-Origin', '*')
    def on_post(self, req, res):
        res.set_header('Access-Control-Allow-Origin', '*')
        print('hey everyone')
        print(req.context)
        res.status = falcon.HTTP_201
        res.body = ('posted up')

contacts_resource = ContactsResource()

app = falcon.API()

app.add_route('/api/contacts', contacts_resource)

I imagine that I’m making a small error in my on_post method, but I can’t tell what it is. I would’ve assumed that at least the print statements would work but they are not.

enter image description here

Asked By: qarthandso

||

Answers:

You need to add a handler for the CORS preflight OPTIONS request the browser sends, right?

The server must respond to the OPTIONS with a 200 or 204 and no response body and include the Access-Control-Allow-Methods and Access-Control-Allow-Headers response headers.

So something like this:

def on_options(self, req, res):
    res.status = falcon.HTTP_200
    res.set_header('Access-Control-Allow-Origin', '*')
    res.set_header('Access-Control-Allow-Methods', 'POST')
    res.set_header('Access-Control-Allow-Headers', 'Content-Type')

Adjust the Access-Control-Allow-Headers value to whatever you actually need.

Or you can use the falcon-cors package:

pip install falcon-cors

…then change your existing code to:

from falcon_cors import CORS

cors_allow_all = CORS(allow_all_origins=True,
                      allow_all_headers=True,
                      allow_all_methods=True)

app = falcon.API(middleware=[cors.middleware])

#declare resources and instantiate it
class ContactsResource(object):

    cors = cors_allow_all

    def on_get(self, req, res):
        res.status = falcon.HTTP_200
        res.body = ('This is me, Falcon, serving a resource HEY ALL!')
    def on_post(self, req, res):
        print('hey everyone')
        print(req.context)
        res.status = falcon.HTTP_201
        res.body = ('posted up')

contacts_resource = ContactsResource()

app.add_route('/api/contacts', contacts_resource)

You may also need to set the allow_credentials_all_origins=True option.

Answered By: sideshowbarker