0

So I'm trying to send some jquery data from the frontend to the backend using Ajax and flask, but I keep getting this error but all of my other code is working fine

I've tried using type: 'POST' and $.post to try to send the data but I have not had much luck. I also tried using request.form and request.get_json(), still no luck.

I tried running a quick test in postman and it told me. I'm trying to run a POST request.

Code from Postman

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The CSRF token is missing.</p>

Python Flask

#all other code is fine...

@users.route('/api/get_msg') #Both users can communicate
def get_msg():
    text = Messages.query.all()
    users = Users.query.all()
    return jsonify([
    {
        "msg": text[m].message,
        "user": text[m].sender.username
    }
    for m in range(len(text))
])

@users.route('/api/send_msg', methods=['POST'])
def send_msg():
    data = request.get_json()
    from_user = current_user
    msg_text = data["msg_text"]
    newMsg = {
    "msg_text": msg_text
    }
    msg_log = Message(message=msg_text, sender=from_user)
    db.session.add(msg_log)
    db.session.commit()
    return jsonify({"result", "success"})

Javascript


 $(function() {
    var $msg_history = $('#messages');
    var $msg_text = $('input #msg_text');
    let $username = $('#current_user_id').data();
    let $other_user = $('#to_send_user_1').data();

    function incoming(text){
      $msg_history.append(`
        <div class="incoming_msg">
          <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>
          <div class="received_msg">
            <div class="received_withd_msg">
            <p><strong>${text.user}</strong>: ${text.msg}</p>
              <span class="time_date">16:09 |   Today</span></div>
          </div>
        </div>
        `);
    }

    function outgoing(text){
      $msg_history.append(`
        <div class="outgoing_msg">
          <div class="sent_msg">
            <p>${text}</p>
            <span class="time_date"> 11:00am </span> </div>
        </div>
        `);
    }

    $.ajax({
      type: 'GET',
      url: '/api/get_msg',
      success: function(data){
        $.each(data, function(i, msgs){
            incoming(msgs);
        });
      },
      error: function(){
        alert('ERROR: Could not load messages. Please try to reconnect.')
      }
    });

// SEND MSG
    var $sendBtn = $('#send_btn');
    var $msg_text = $('#msg_text');

    $sendBtn.on('click', function(event){
      event.preventDefault();
      $.ajax({
        type: 'POST',
        url: '/api/send_msg',
        data: {
          "msg_text": $msg_text.val()
        }
      })
      .done(function(data){
        if (data.error){
          outgoing('Could Not Send');
        }
        else{
          outgoing($msg_text.val());
        }
      });
      $msg_text.val('');
    });
});

HTML or The Template via Jinja2

<div class="mesgs">
          <div class="msg_history" id="messages">
           <!-- Some other Code-->
          </div>

          <div class="type_msg" id="messageInput">
            <div class="input_msg_write">
              <input type="text" class="write_msg" id="msg_text" name="msg_text" placeholder="Type a message" />
              <button class="msg_send_btn" id="send_btn" type="button">Send</button>
              </div>
          </div>
</div>

I'm trying to have the backend save the message to the database and then send it back to the frontend via a get request. Just like a chat app.

I'm also trying to find out the best way to create an instant chat application using flask and jquery. If anyone has some suggestions. please let me know. I'm already using pusher for pushing the messages in real time.

Ty Cooper
  • 41
  • 4
  • 1
    HTTP Error 400 generally means that there is some required parameter that is either missing from your request, or invalid. – Anis R. Jun 13 '19 at 21:13

1 Answers1

1

The HTTP 400 tells you that you're missing a CSRF token. This is used to authenticate data sent to the server, either by forms or JS. Flask requires it for forms, and won't validate the data unless you include form.hidden_tag() in your Jinja template.

I'm a little confused about why you're getting an error about it here, though. As far as I'm aware, Flask doesn't enforce CSRF tokens on AJAX requests by default. And you're not sending a form request, right? Are you importing CSRFProtect already? If so, then this is the problem, and you just need to include that token in the headers when you send the AJAX request.

As an aside, I think you might have intended to use a colon here:

return jsonify({"result", "success"})
Nick K9
  • 3,885
  • 1
  • 29
  • 62