5

I'm working on a Flask app. One of my views contains dynamically created elements. In order to collect the values and write them my MongoDB database, I created a JS script that goes over the elements and extracts the values to JS variables. After that I POST them to my Flask backend through an AJAX $.post() method. That part works correctly, but when getting to the end of my @app.route function, and I try to redirect to another landing page, I get the following error:

Mixed Content: The page at 'https://cocktail-recipe-book-gabyguedezh.c9users.io/get_add_cocktail_form' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://cocktail-recipe-book-gabyguedezh.c9users.io/get_my_recipes'. This request has been blocked; the content must be served over HTTPS.

The POST itself gets executed and the form sends a document to my database, however, the redirect doesn't happen.

The entire backend route looks like this:

@app.route('/write_to_cocktail_database', methods=['POST'])
def write_to_cocktail_database():
    recipes = mongo.db.recipes

    recipes.insert_one(request.json)

    return redirect(url_for('get_my_recipes'))

Just in case, the AJAX function looks like this:

$.ajax({
    url: formUrl,
    // data: {'data': steps},
    data: JSON.stringify({recipe_name,  recipe_url, recipe_description,
                        recipe_image, is_vegan, ingredients, steps,
                        base_spirit, cocktail_type, flavour_profile,
                        author_name, recipe_rating, number_of_votes}, null, '\t'),
    type: 'POST',
    contentType: 'application/json;charset=UTF-8',
    success: function(response) {
        console.log('success');
    },
    error: function(error) {
        console.log('error', error);
    }
});

I've tried the following:

SSL for particular views as seen HERE

I tried to copy that code at the beginning of my app (including the imports) and then using the @ssl_required decorator below the @app.route like this:

@app.route('/write_to_cocktail_database', methods=['POST'])
@ssl_required
def write_to_cocktail_database():
    <rest of function>
    return redirect(url_for('get_my_recipes'))

Where get_my_recipes is the route I'm trying to redirect to. This didn't work

I also tried to work around it with a replace method inside of the function like this:

if request.url.startswith('http://'):
        request.url = request.url.replace('http://', 'https://', 1)

That didn't work either, as I don't know how to feed the modified URL to the redirect's url_for (and simply doing redirect(modified_url_as_string) doesn't work either).

Now, I know the get_my_recipes route works in other redirects, for example:

@app.route('/delete_cocktail/<recipe_id>')
def delete_cocktail(recipe_id):
    mongo.db.recipes.remove({'_id': ObjectId(recipe_id)})
    return redirect(url_for('get_my_recipes'))

The above, deletes a recipe and redirects to "My Recipes" page.

I'm not sure why the POST from the AJAX function I wrote doesn't redirect me, but the POST from a regular HTML <form> does work.

I'm also not sure how to use the decorator from the snippet I found (in the link above), as I though simply adding the decorator before the route would work.

I've also tried other workarounds, such as a redirect through jQuery on the success portion of the AJAX function like this window.location.href = "https://cocktail-recipe-book-gabyguedezh.c9users.io/get_my_recipes"; (it also complained that the redirect was not secure). I tried to work around the redirect by simply doing render_template('my_recipes.html') but this didn't work either, it seems it has to be a redirect on the return for the route.

I'm new at web development and Flask, so I'm not sure how to use the snippet I found in other SO answers (such as this one where the accepted answer seems to be a general decorator I placed before all my routes, but that lead to a "too many redirects error", which was resolved vaguely in the comments and I don't know what it means).

I've been looking around for answers that I could use but I'm frustrated as most answers I've found assume working knowledge of Flask and most provide no concise examples on how to use the code (such as 1).

I would greatly appreciate some sort of direction here, I don't know how to proceed anymore.

  • 1
    Welcome to stackoverflow, very nice first question, well done :-) Unfortunately don't have time for a full answer, but I'd [suggest looking here](https://stackoverflow.com/questions/47372745/flask-response-to-a-post-confusing-behaviour/47372966#47372966) for some hints on redirect behaviour with AJAX vs form submit. – bgse Sep 02 '18 at 09:59

0 Answers0