首页 > 解决方案 > 会话数据不与 Flask 会话保持一致

问题描述

I recently moved from Python 2.7 to Python 3.7 for some of my production servers. I am having some trouble with session data using flask. I currently manage customer's cart data using sessions. Now, this is fine almost all of the time, but once every now and again my customer's cart data is completely empty.

The flow is, a customer puts items into their cart, which is all managed by a Javascript plugin. When the customer navigates to the checkout window, I do an Ajax call to my Flask Python backend and create the session data to store the customer's cart. This call is as so:

   $.ajax({
        url: '/order_now_homepage',
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        success: function(response){
            console.log(response);
            if(response == 'OK'){
                window.location.replace("/checkout");
            }
            else{
                console.log("Problem passing cart_data to server");
            }
        },
        data: JSON.stringify(jsonData)

})

This then passes in to the following function:

@app.route('/order_now_homepage', methods=['POST'])
def order_now_homepage():
    cart_data = dict(request.json)
    cart_total = 0

    for k, v in cart_data.iteritems():
        cart_total += float(v['total'])
        v['price'] = float(v['price'])

    session['cart_data'] = cart_data
    session['cart_total'] = cart_total + 2.00
    session.modified = True
    return jsonify('OK')

And then, the Ajax call redirects the user to the checkout window. This all works fine. The checkout window call is as so:

@app.route('/checkout')
def checkout():
    print(session)
    cart_data = session['cart_data']
    cart_total = session['cart_total']
    return render_template("checkout.html", data = cart_data, total = cart_total, key=stripe_keys['publishable_key'], val_post = app.config['ALLOWED_POSTCODES'])

Now, the problem arises when I am then trying to re-access to cart data when the user presses the 'Pay with card' button on their checkout window. I am using Stripe so I have a 'create-checkout-session' endpoint that attempts to build a Stripe charge using the cart data in the session variable session['cart_data'] which is as follows:

@app.route('/create-checkout-session', methods=['POST'])
def create_checkout_session():
    data = json.loads(request.data)
    domain_url = DOMAIN
    cart_data = session['cart_data']
    input_offer = data['offer'] 

    charge_amt = get_charge_amount(data['del_type'], input_offer, cart_data)

    if not get_charge_holidays(data['del_date']):
        try:
            checkout_session = stripe.checkout.Session.create(
                success_url=domain_url +
                "/success_checkout?session_id={CHECKOUT_SESSION_ID}",
                billing_address_collection="auto",
                shipping_address_collection={
                        'allowed_countries': ['GB'],
                          },
                cancel_url=domain_url + "/canceled_checkout",
                payment_method_types=["card"],
                metadata = {"contact_number" : data['contact'],
                            "del_date" : data['del_date'],
                            "del_type" : data['del_type'],
                            "validated_postcode" : data['postcode']},
                line_items = charge_amt
            )

            return jsonify({'sessionId': checkout_session['id']})
        except Exception as e:
            print(e)
            return jsonify(error=str(e)), 403
    else:
        return jsonify(error="This date you have tried to place an order for is no longer available"), 400

The issue arises at the line in the 'create-checkout-session' call when I am attempting to assign cart_data = session['cart_data']. Once every 20-30 customers, they trigger a KeyError on the session data something like the following:

2020-05-24T18:48:45.430193+00:00 app[web.1]: [2020-05-24 18:48:45,429] ERROR in app: Exception on /create-checkout-session [POST]
2020-05-24T18:48:45.430201+00:00 app[web.1]: Traceback (most recent call last):
2020-05-24T18:48:45.430202+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 2311, in wsgi_app
2020-05-24T18:48:45.430202+00:00 app[web.1]: response = self.full_dispatch_request()
2020-05-24T18:48:45.430202+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1834, in full_dispatch_request
2020-05-24T18:48:45.430203+00:00 app[web.1]: rv = self.handle_user_exception(e)
2020-05-24T18:48:45.430203+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1737, in handle_user_exception
2020-05-24T18:48:45.430203+00:00 app[web.1]: reraise(exc_type, exc_value, tb)
2020-05-24T18:48:45.430204+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/_compat.py", line 36, in reraise
2020-05-24T18:48:45.430204+00:00 app[web.1]: raise value
2020-05-24T18:48:45.430205+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1832, in full_dispatch_request
2020-05-24T18:48:45.430205+00:00 app[web.1]: rv = self.dispatch_request()
2020-05-24T18:48:45.430205+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1818, in dispatch_request
2020-05-24T18:48:45.430206+00:00 app[web.1]: return self.view_functions[rule.endpoint](**req.view_args)
2020-05-24T18:48:45.430206+00:00 app[web.1]: File "/app/app/views.py", line 171, in create_checkout_session
2020-05-24T18:48:45.430206+00:00 app[web.1]: cart_data = session['cart_data']
2020-05-24T18:48:45.430207+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/werkzeug/local.py", line 378, in <lambda>
2020-05-24T18:48:45.430207+00:00 app[web.1]: __getitem__ = lambda x, i: x._get_current_object()[i]
2020-05-24T18:48:45.430207+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/sessions.py", line 83, in __getitem__
2020-05-24T18:48:45.430207+00:00 app[web.1]: return super(SecureCookieSession, self).__getitem__(key)
2020-05-24T18:48:45.430208+00:00 app[web.1]: KeyError: 'cart_data'

Can someone please advise?

Thank you!

标签: javascriptpythonpython-3.xajaxflask

解决方案


推荐阅读