【问题标题】:Can't get image upload to work with Flask and JQuery无法让图像上传与 Flask 和 JQuery 一起使用
【发布时间】:2021-12-14 19:47:27
【问题描述】:

以下代码允许您使用 AJAX 和 JQuery 从 Flask 提交表单并返回文本的变体:

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('form.html')

@app.route('/process', methods=['POST'])
def process():

    email = request.form['email']
    name = request.form['name']

    if name and email:
        newName = name[::-1]

        return jsonify({'name' : newName})

    return jsonify({'error' : 'Missing data!'})

if __name__ == '__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
    <title>AJAX Example</title>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

    <script src="{{ url_for('static', filename='js/form.js') }}"></script>
</head>
<body>
<div class="container">
    <br><br><br><br>
    <form class="form-inline">
      <div class="form-group">
        <label class="sr-only" for="emailInput">Email address</label>
        <input type="email" class="form-control" id="emailInput" placeholder="Email">
      </div>
      <div class="form-group">
        <label class="sr-only" for="nameInput">Name</label>
        <input type="text" class="form-control" id="nameInput" placeholder="First Name">
      </div>
      <button type="submit" class="btn btn-default">Submit</button>
    </form>
    <br>
    <div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
    <div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
</div>
</body>
</html>
$(document).ready(function() {

    $('form').on('submit', function(event) {

        $.ajax({
            data : {
                name : $('#nameInput').val(),
                email : $('#emailInput').val()
            },
            type : 'POST',
            url : '/process'
        })
        .done(function(data) {

            if (data.error) {
                $('#errorAlert').text(data.error).show();
                $('#successAlert').hide();
            }
            else {
                $('#successAlert').text(data.name).show();
                $('#errorAlert').hide();
            }

        });

        event.preventDefault();

    });

});

但是当我稍微修改代码以对上传的文件名做同样的事情时,它就不起作用了。我所做的只是更改表单的类型,以便它接收文件,然后使它反转文件名而不是以前版本的输入文本。你知道我在这里做错了什么吗?

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('form.html')

@app.route('/process', methods=['POST'])
def process():

    filename = request.files['file'].filename

    if filename:
        newName = filename[::-1]

        return jsonify({'name' : newName})

    return jsonify({'error' : 'Missing data!'})

if __name__ == '__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
    <title>AJAX Example</title>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

    <script src="{{ url_for('static', filename='js/form.js') }}"></script>
</head>
<body>
<div class="container">
    <br><br><br><br>
    <form method="POST" action='/process' enctype="multipart/form-data">
        <div>
          <label for="file">Choose file to upload</label>
          <input type="file" id="file" name="file">
        </div>
        <div>
          <button type="submit" class="btn btn-default">Submit</button>
        </div>
       </form>
    <br>
    <div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
    <div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
</div>
</body>
</html>
$(document).ready(function() {

    $('form').on('submit', function(event) {

        $.ajax({
            data : {
                
                file : $('#file')
            },
            type : 'POST',
            url : '/process'
        })
        .done(function(data) {

            if (data.error) {
                $('#errorAlert').text(data.error).show();
                $('#successAlert').hide();
            }
            else {
                $('#successAlert').text(data.name).show();
                $('#errorAlert').hide();
            }

        });

        event.preventDefault();

    });

});

【问题讨论】:

    标签: javascript python jquery ajax flask


    【解决方案1】:

    如果您使用 FormData 类型的对象来序列化和传输表单的数据,它应该可以工作。

    $(document).ready(function() {
      $('form').submit(function(event) {
        let formData = new FormData(event.target);
        $.ajax({
          data: formData,
          type : 'POST',
          url : '/process',
          contentType: false,
          processData: false
        })
        .done(function(data) {
          if (data.error) {
            $('#errorAlert').text(data.error).show();
            $('#successAlert').hide();
          } else {
            $('#successAlert').text(data.name).show();
            $('#errorAlert').hide();
          }
        });
        event.preventDefault();
      });
    });
    

    【讨论】:

    • 这似乎没有解决问题 - 与原始代码不同,它只是重定向到带有“JSON”、“原始数据”和“标题”的屏幕,而不是打印出反向原始页面中的文件名
    • @tewerty 对不起。修改了我的答案。
    • 非常感谢 - 现在运行良好!请问这两行代码有什么区别,为什么?
    • @tewerty contentType: false 防止 jQuery 自动设置内容类型。 processData: false 防止将数据转换为字符串。这意味着使用了 FormData 对象的设置。
    • 我也可以问一下 event.preventDefault() 在这里完成了什么?
    猜你喜欢
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多