Making a post request using AJAX in Javascript to a Python Flask Server Backend and receiving a 415 error

I am fairly new to web development so I apologize if my terminology is off, but some friends and I are working on a personal project website and I have not been able to find a lot of information relevant to our exact tech stack/issues so I am braving the stack overflow forms. If anyone reads through this and knows where to find relevant documentation I should read (even if you aren’t sure of an exact answer to my problem) sharing it would be greatly appreciated. We have a limited budget of 0 dollars and as a result are hosting our Flask backend on a pythonanywhere site and we are hosting our frontend on a GitHub Jekyll site. Originally we were going to make requests from our front end to our back end using JavaScript’s fetch function and pass the parameters our backend needed through our URL but we quickly realized we needed to pass a lot of parameters and this would be clunky. So after some research we found out we could add the AJAX library to our project and make a POST request sending a JSON along with our request which the back end could then parse for all our parameters and send us back the needed information. However, I have been unable to successfully make a POST request after about a week of on and off scouring the internet for similar examples.

The first issue we were running into was a CORS issue which seemed to be due to our front end and our back end being hosted at different spots. (Note that I am using local host here for testing purposes but the same issues still arise.)

This was solved by configuring our python code like so:

from flask import Flask, after_this_request, jsonify, request

app = Flask(__name__)

@app.route("/testRoute", methods=['POST', 'GET'])
def testRoute():

    #boilerplate code, dont touch this
    @after_this_request
    def add_header(response):
         response.headers.add('Access-Control-Allow-Origin', '*')
         return response

    if request.method == 'POST':
        print("test")
        elems = request.json
        print(elems)
        return jsonify({})

    return jsonify({'goodbye':'world'})

And our JavaScript code like so:

function sendData() {
    $.ajax({
        type : 'POST',
        url : 'http://127.0.0.1:5000/testRoute',
        data : {'hello':'world'},
        success: function(response) {
            console.log(response);
        },
        error: function(error) {
            console.log(error);
        }
    })
}

Which led to a 415 error when calling the JavaScript code.

One Stack Overflow post suggested adding a header to our Javascript request like so:

function sendData() {
    $.ajax({
        type : 'POST',
        headers : {
            'Content-type':'application/json', 
            'Accept':'application/json'
        },
        url : 'http://127.0.0.1:5000/testRoute',
        data : {'hello':'world'},
        success: function(response) {
            console.log(response);
        },
        error: function(error) {
            console.log(error);
        }
    })
}

However making the request with these headers added gives a response of “Access to XMLHttpRequest at ‘http://127.0.0.1:5000/testRoute’ from origin ‘null’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.” Which I assume is the CORS error from before.

Another post suggested changing the Python file to:

from flask import Flask, after_this_request, jsonify, request

app = Flask(__name__)

@app.after_request
def after_request(response):
    header = response.headers
    header['Access-Control-Allow-Origin'] = '*'
    header['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, Accept'
    header['Access-Control-Allow-Methods'] = 'OPTIONS, HEAD, GET, POST, DELETE, PUT'
    return response

@app.route("/testRoute", methods=['POST', 'GET'])
def testRoute():

    if request.method == 'POST':
        print("test")
        elems = request.json
        print(elems)
        return jsonify({})

    return jsonify({'goodbye':'world'})

As well as removing the headers from our JavaScript function. However, this still just gave us the 415 error.

I have also tried formatting the headers with some additional information as a third post suggested:

function sendData() {
    let headers = new Headers();

    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');
    headers.append('Access-Control-Allow-Origin', 'http://127.0.0.1:5000/testRoute');
    headers.append('Access-Control-Allow-Credentials', 'true');

    $.ajax({
        type: 'POST',
        headers: headers,
        data : {'hello':'world'},
        success: function (e) {
            console.log(e);
        },
        error: function(error) {
            console.log(error);
        }
   }); 
}

But this still led to the above CORS issues.

A fourth post also suggested changing the the elems = request-get_json line like so:

elems = request.get_json(force=True) 

And I tested with various different header settings in both the JavaScript and Python files but to no avail.

I am starting to feel like I am going in circles, this seems like it should be an easy issue to fix but I think I just lack the knowledge about this subject to understand which headers to change and why. Seemingly if the Flask Server sends a response header then the JavaScript isn’t allowed to include any headers with its request, but if the Flask Server doesn’t have the headers then we run into the CORS issues.