【问题标题】:File upload using Flask and jQuery使用 Flask 和 jQuery 上传文件
【发布时间】:2017-04-10 22:45:19
【问题描述】:

我在编写使用 jQuery 中的 ajax 调用发送 html 表单的程序时遇到问题。 这是我的 upload.html 和 form.js 文件:

$(document).ready(function() {

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

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

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

		});

		event.preventDefault();

	});

});
<!DOCTYPE html>
<html lang="en">
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <meta charset="UTF-8">
    <title>File Upload</title>
    <script type=text/javascript src="{{ url_for('static', filename='form.js') }}"></script>
</head>
<body>
<h1>Please upload all the corresponding files</h1>
<div id="upload">
    <form id="upload-hc" >
        <input type="file" name="file" accept=".csv" id="hc">
        <input type="submit" value="go">
    </form>
    <br>
    <p id="successAlert" style="display:none;">Success!</p>
	<p id="errorAlert" style="display:none;">Fail!</p>


</div>

<script>

</script>

</body>
</html>

这是我的 Flask 服务器:

import os
from flask import Flask, render_template, request, jsonify

app = Flask(__name__)
APP_ROOT = os.path.dirname(os.path.abspath(__file__))

@app.route("/")
def index():
    return render_template("upload.html")


@app.route("/uploadhc", methods=['POST'])
def uploadhc():
    target = os.path.join(APP_ROOT, "DataSource/")


    if not os.path.isdir(target):
        os.mkdir(target)
    print request.files
    if 'file' not in request.files:
        error = "Missing data source!"
        return jsonify({'error': error})


    file = request.files['file']
    fileName = "DCData.csv"
    destination = '/'.join([target, fileName])
    file.save(destination)


    success = "Success!"
    return jsonify({'file': success})


if __name__ == "__main__":
    app.run(port=4555, debug=True)

当我尝试选择一个 csv 文件并提交 HTML 表单时,服务器说 request.files 是 ImmutableMultiDict([]),它是空的。知道如何将文件发送到我的服务器吗?谢谢!

【问题讨论】:

    标签: javascript jquery python html ajax


    【解决方案1】:

    您需要将表单作为分段上传发送,您可以将整个表单转换为FormData(formElement)

    var form = $('#upload-hc')[0]
    var fd = new FormData(form)
    
    $.ajax({
      type : 'POST',
      url : '/uploadhc',
      data: fd,
      processData: false,  // tell jQuery not to process the data
      contentType: false   // tell jQuery not to set contentType
    })
    

    如果你有兴趣,这里有一个 es6 版本

    // short for jquery(function($){ ... })
    // which is the equvilant to $(document).ready(function($) {
    jQuery($ => {
      
      $('form').on('submit', event => {
        event.preventDefault()
        
        let form = $('#upload-hc')[0]
        let fd = new FormData(form)
    
        fetch('/uploadhc', {method: 'POST', body: fd})
        .then(res => {
          // console.log(res.ok)
          return res.json() // or res.text, res.arraybuffer
        })
        .then(result => {
          console.log(result)
        })
      })
      
    })

    【讨论】:

    • 谢谢!我试过 FormData([formElement]),但是 ImmutableMultiDict([]) 还是空的
    • 你试过没有[]吗?
    • 是的。但是我的服务器仍然无法获取表单数据
    【解决方案2】:

    在html端:

    <input type="file" id="uploadfile" name="NewCsvUpload">
    

    在javascript方面:

    var form_data = new FormData();
    form_data.append('file', $('#uploadfile').prop('files')[0]);
    
    $(function() {
    $.ajax({
        type: 'POST',
        url:  '/uploadLabel',
        data: form_data,
        contentType: false,
        cache: false,
        processData: false,
        success: function(data) {
            console.log('Success!');
        },
      })
    });
    

    在服务器端:

    @app.route('/uploadLabel',methods=[ "GET",'POST'])
    def uploadLabel():
        isthisFile=request.files.get('file')
        print(isthisFile)
        print(isthisFile.filename)
        isthisFile.save("./"+isthisFile.filename)
    

    【讨论】:

      【解决方案3】:

      当我过去这样做时,我总是将enctype="multipart/form-data" 放在form div 中。

      这里有几个链接可以更详细地解释它:

      【讨论】:

      • 是的。但我不认为添加“enctype”在这里有帮助。
      猜你喜欢
      • 2018-03-02
      • 2015-02-22
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多