1

I am trying to upload a csv file to a Flask server and I do not want the page to be reloaded, so I am trying to implement ajax. However, I cannot get it to work. Here is a minimal working example.

app.py

import os.path
from flask import Flask, render_template, request
 
app = Flask(__name__, static_url_path='', static_folder='static', template_folder='templates')
app.config['UPLOAD_FOLDER'] = './upload/'

@app.route("/", methods=["POST", "GET"])
def home():
    if request.method == "POST":
        f = request.files['todo']
        f.save(os.path.join(app.config['UPLOAD_FOLDER'], 'upload.csv'))
        return 'this should not be printed'
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

templates/index.html

<!DOCTYPE html>
<html>
<body>
  <form method="post" id="todo-form" enctype="multipart/form-data">
    <input type="file" name="todo" id="todo">
    <button type="submit">submit</button>
  </form>
  <script src="https://code.jquery.com/jquery-3.5.1.js"
          integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
          crossorigin="anonymous"></script>
  <script src="test.js"></script>
</body>
</html>

static/ajax.js

$(document).on('submit', '#todo-form', function(e) {
  const fd = new FormData(this);
  e.preventDefault();
  $.ajax({
    type: 'POST',
    url: '/',
    data: fd,
    contentType: false,
    processData: false,
    complete: function() { alert('saved');},
  })
});

The reloading action is now prevented, and the alert is now shown, but the file is not uploaded. Can someone tell me what I did wrong? Thank you very much!

cssstudent
  • 96
  • 7
  • 2
    `$(todo-form)` is invalid syntax. There will be an error message in your dev-tools console. All you really need is `new FormData(this)` since the `
    ` element is bound to `this` by jQuery automatically
    – Phil Sep 12 '22 at 03:38
  • `` should be ``. See also [this answer](https://stackoverflow.com/a/68643919/283366) for how to get jQuery to upload files. In short you need to set `contenType` and `processData` to `false` – Phil Sep 12 '22 at 03:39
  • Sorry I accidentally posted a older version of the code. I have now changed the input type back to file and attached the correct enctype. – cssstudent Sep 12 '22 at 03:43
  • Doesn't change anything else I mentioned – Phil Sep 12 '22 at 03:44
  • 1
    Make sure you clear your browser cache. They are very good at storing old copies of `.js` files – Phil Sep 12 '22 at 03:58
  • Yes, that is the issue, thank you very much. The code works as intended. How do I prevent the cache from screwing me up? Will app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 solve my problem? – cssstudent Sep 12 '22 at 04:02
  • 1
    I'm no Python dev but that looks right according to [this answer](https://stackoverflow.com/a/24670914/283366) – Phil Sep 12 '22 at 04:04
  • Does this answer your question? [How to prevent page reload on form input with FastAPI](https://stackoverflow.com/questions/73356104/how-to-prevent-page-reload-on-form-input-with-fastapi) – Chris Sep 12 '22 at 05:20
  • Please have a look at [this answer](https://stackoverflow.com/a/73358937/17865804) as well. – Chris Sep 12 '22 at 05:20

1 Answers1

-1

As pointed out by Phil, this is caused by the storage of browser cache. The code works as intended once the cache is cleared.

cssstudent
  • 96
  • 7