0

I'm facing a strange issue with a Flask single app and a jQuery AJAX call I'm making via a form in the view. Basically, the endpoint (/register) is called correctly when I debug the JS code, but when I try to run normally, the endpoint is never called, I can see in the Network view that the request is sent, but it seems that it never reaches Flask.

That said, this is my html code (the relevant parts concerning the form and the JS code):

<form action="" method="" id="newsletter-form" role="form">
    <div class="input-group">
        <input type="email" name="user_email" class="newsletter-email form-control" placeholder="ENTER EMAIL ADDRESS">
        <span class="input-group-btn">
            <button value="" type="submit" class="btn btn-green waves-effect waves-light newsletter-submit">Get More Info</button>
        </span>
    </div>
    <div id="ajax-panel"></div>                               
</form>

Here is the JS code, based on this SO answer, I've added the event.preventDefault() stuff:

function makeRequest(event){
        event.preventDefault(); //stop the form from being submitted

        $.getJSON($SCRIPT_ROOT + '/register', {
                    user_email: $('input[name="user_email"]').val()
                  },
                function(data) {
                        $('#ajax-panel').empty();
                            if (data.status == 'OK'){
                                $('#ajax-panel').append('<div class="success"><strong>' + data.message + '</div>');
                            }
                            else{
                                $('#ajax-panel').append('<div class="error"><strong>' + data.message + '</div>');
                            }
                });
        return false;
    }

    $('#newsletter-form').submit(function(event){
        makeRequest(event);
    });

And here is the Flask code for that endpoint:

@app.route('/register', methods=['GET', 'POST'])
def register():
    error = None
    user_email = request.args.get('user_email', 0, type=str)

    try:
        form = RegisterForm(email=user_email)
        if form.email.data and valid_mail(form.email.data):
            from models import RegisteredMail
            new_rm = RegisteredMail(
                form.email.data,
                datetime.datetime.utcnow(),
            )
            try:
                db.session.add(new_rm)
                db.session.commit()
                message = 'Thanks for subscribing, we will keep you posted!'
                return json.dumps({'status': 'OK', 'message': message})
            except IntegrityError:
                message = 'Provided email is already used, please use a different one'
                return json.dumps({'status': 'ERROR', 'message': message})
        else:
            message = 'Provided email is invalid, please use a different one'
            return json.dumps({'status': 'ERROR', 'message': message})
    except Exception as e:
        print e
        return render_template('index.html')

As I said, this works perfectly fine if I debug, but when running it does not...I'm scracthing my head here. It looks like if the request never reaches the server, because if I CTRL-C the server, I get the error in JS side, which looks like something is "blocking" the form submission...any clues?

EDIT

I've found the issue, and it had nothing to do with a wrong request or any on the server side...

I had a video tag that was used to stream a video that I had stored in my static/video folder, about 50MB size. Well, I started to comment out big chunks of the view code doing trial & error stuff. It looks that that piece of code was the one causing trouble...

<video class="img_responsive" controls>
    <source src="{{ url_for('static', filename='video/movie.mp4') }}" type="video/mp4">
    Your browser does not support the video tag.
</video>

I'm still not 100% sure, but I was getting random exceptions using the above code:

Traceback (most recent call last): 
File "/usr/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock self.process_request(request, client_address) 
File "/usr/lib/python2.7/SocketServer.py", line 321, in process_request self.finish_request(request, client_address) 
File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request self.RequestHandlerClass(request, client_address, self) 
File "/usr/lib/python2.7/SocketServer.py", line 657, in init self.finish() 
File "/usr/lib/python2.7/SocketServer.py", line 711, in finish self.wfile.flush() 
File "/usr/lib/python2.7/SocketServer.py", line 303, in flush self._sock.sendall(view[write_offset:write_offset+buffer_size])

I really have no clue why this is happening, I've changed to dropbox to act as CDN streaming server for that video and eveything goes great...if anyone has an explanation for this, I'd like to hear it :), otherwise this goes to the X-Files section.

Community
  • 1
  • 1
AlejandroVK
  • 7,373
  • 13
  • 54
  • 77

1 Answers1

1

I know this shouldn't make much difference since it is the basically the same code but you could try and and use ajax like this to make your get request.

$.ajax({
  url: "/register?userEmail=" + $('input[name="user_email"]').val(),
  type: "GET",
  success: function(data){
     if(data.status = "OK"){
        //All is good
     }else{
       //There was an error
     }
  }
  error: function(xhr, ajaxOptions, thrownError){
     //If something brakes
     alert(xhr.status);
     alert(thrownError);
  }
});
Igor Ilic
  • 1,370
  • 1
  • 11
  • 21
  • @AlejandroVK can you gives a link to your website if it is live, so I could test and see what happens. I had a similar problem on one of my sites. Usually it was because of multiple ajax requests at once. Because sometimes one request completes and tries to call the result of an another request that hasn't completed yet and that is why this is happening. Because Ajax is asynchronous, which means it will no load one by one, but actually all at ones and it basically first come, first served principle. – Igor Ilic Oct 29 '15 at 10:28
  • I'm sorry I can't, this is not production ready yet. Anyway, I've found the cause, check my updated response. Thanks @Igor! – AlejandroVK Nov 02 '15 at 08:35