Flask Workaround for JS cross scripting rules

I am running a Flask site on my local machine and I want to display some data from an API. In this case, I want to use the Qualtrics API to display survey data that was collected the previous day. I should be able to use Jquery to send a GET request like this:

But this does not work. My Javascript console gives me the following message:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access.

The Qualtrics API sends a response indicating that my site (localhost) is not allowed to access it. This is an over simplification and I am in no way an expert on CORS headers. You should check out this StackOverflow thread for a much better explanation. The moral of the story is I will not be able to access this data with an AJAX request.


However, because I am running my site in Flask I can have Python do the request and use a route to serve the response. I prefer to use Requests for all my HTTP needs, but similar libraries would also work. I can call the Qualtrics API, or any API for that matter, using requests like so:

My variable, r, now holds the Requests object which I can call different methods on:

> r.status_code
200
> r.text
>>> r.text
u'{"R_3mmAjotjgKFliBba":{"ResponseSet":"Default Response Set"...
>>> r.json()
{u'R_1OfQIHWo1fMmK3L': {u'Q3': u'This is a survey answer...

The text and json methods both return the data I am looking for; text returns unicode and json returns a python dict. Now I need a way to access it on the page. I will combine the code above into a new Flask route that looks like this:

Here I am defining a route titled responses that returns the JSON from a Requests GET request. As mentioned above, the .json() method returns a dict. In order to call this via AJAX in my Javascript call I will need to convert it back to JSON. I use Flask’s built-in jsonify method to do this. I am specifically using jsonify instead of Python’s built in json.dumps because jsonify returns a Flask response object with a header of application/json. Dumps on the other hand just returns an encoded string which is not what I need. On a final routing note, if I were being prudent with my Blueprints, I would separate the API routes into a different component with the route prefix of @api.


Now that I have the route defined, I can call the URL just like I would with any other API. My Jquery now looks like this:

Successful logging of the object

I can now use the API that was previously restricted by cross-scripting rules by building my own API route within my Flask application.