【问题标题】:Flask - Empty Files When UploadedFlask - 上传时的空文件
【发布时间】:2020-12-03 04:01:03
【问题描述】:

我有一个项目允许用户上传文件,他们最终会得到处理,然后提供结果文件。

我刚刚意识到,现在我正在尝试实现系统的处理部分,上传时文件是空的,我不确定哪里出了问题。文件已成功命名并放入目录,但为空。

任何帮助将不胜感激。

上传的html表单:

<div class="tile is-vertical is-parent coach" id='fileUploadTile'>
  <div class="tile is-child box has-background-light">

      <form action='/' method='POST' enctype="multipart/form-data">
        <div class='drop-zone'>
          <span class='drop-zone__prompt is-family-monospace'>Drag and drop or click here to upload files</span>

          <input class="drop-zone__input" type="file" multiple name="uploaded_file" id='fileLoader'>

        </div> <!-- end of drop-zone-->
        <div class='buttons are-medium' id='fileButtons'>
          <input type='submit' class="button is-success is-light is-outlined is-family-monospace" id='submitFiles' value='Process file(s)'>
          </form>
          <button class='button is-danger is-light is-outlined is-family-monospace' name='resetFiles' id='resetFiles'>Reset File(s)</button>
        </div> <!-- end of buttons -->
       
    </div> <!-- end of tile is-child -->
   

  </div> <!-- end of tile is-vertical -->

尝试验证文件(检查扩展名、文件大小、名称等)然后保存的代码:

def file_upload():
    if session:
        session_name = session.get('public_user')
        print("New request from " + str(session_name))
        # update when last request was sent
        active_sessions[session_name] = datetime.now()
    else:
        session_token = generate_session_token()
        print("Generating new session... " + session_token)
        session['public_user'] = session_token  # session = key, last request = value
        active_sessions[session_token] = datetime.now()
        os.mkdir('uploads/'+session['public_user']) #create directory for uploaded files

    if request.method == "POST":
        if request.files:
            files_processed = True
            files = request.files.getlist("uploaded_file")
            upload_path = app.config['UPLOAD_FOLDER'] + \
                str(session['public_user'])
            # loop, as possibility of multiple file uploads
            for file_to_upload in files:
                file_to_upload.seek(0, os.SEEK_END)
                file_length = file_to_upload.tell()
                file_name = check_existing_file_name(file_to_upload.filename)
                # Secures file name against user input
                file_name = secure_filename(file_name)
                # Checks the file name isn't blank
                if file_to_upload.filename == "":
                    print("Error with file" + file_to_upload.filename +
                          " - name must not be blank")
                    files_processed = False
                    continue
                # Checks the file has an allowed extension
                elif not allowed_ext(file_to_upload.filename):
                    print("Error with file" + file_to_upload.filename +
                          " - extension not supported")
                    files_processed = False
                    continue
                # Checks file size
                elif file_length > app.config['MAX_FILE_SIZE']:
                    print("Error with file" +
                          file_to_upload.filename + " file too big")
                    files_processed = False
                    continue
                else:  # Else, passes all validation and is saved.
                    file_path = upload_path + "/" + file_name
                    file_to_upload.save(file_path) 
            # If files have been processed, return a render with success message
            if files_processed is True:
                return render_template('index.html', is_home='yes', succ="Now processing your files...")
            else:  # Else, normal redirect.
                return redirect(request.url)
        else:  # If no files request, redirect to index.
            return redirect(request.url)
    else:  # If not a POST request, load page as normal.
        return render_template('index.html', is_home='yes')

对不起,如果这是我错过的简单或愚蠢的事情 - 这是我在 Python 中的第一个项目,也是我第一次使用 Flask。

【问题讨论】:

  • 你能看到文件是否真的被发送了吗?
  • 我收到一个成功的 POST 请求,它们出现在 request.files 中,例如 ImmutableMultiDict([('uploaded_file', ), ('uploaded_file', ), ('uploaded_file', )] )
  • 所以你知道这不是 html 发送数据的问题。我建议按照 JG 所说的做,并使用调试器并遍历它。
  • 干杯 - 希望能够抓住它。 :)
  • 我希望你这样做!调试器是我的首选。我从他们那里学到了很多。不知道大家是怎么处理编译代码的

标签: python flask


【解决方案1】:

这一切看起来都不错。

无关:我会针对 file_name 而非 file_to_upload.filename 检查空文件名。

关于您的问题: 唯一明智的答案可能是,通过您的许多操作中的任何一个,您将文件指针放在文件末尾,而 save 无法处理它。

很遗憾,我没有时间在我的电脑上尝试这个,所以请再做一次seek 0 - 这次就在你调用save 方法之前。

我稍后会尝试这个并相应地更新我的答案。

另一种找出发生了什么的方法是使用调试器。这不是太复杂。

我制作了一个 5 分钟的视频 - 仅用于调试 Flask:https://www.youtube.com/watch?v=DB4peJ1Lm2M

【讨论】:

  • 感谢 J.G,非常感谢。等我做完晚饭有时间再看看。谢谢你的视频 - 我相信它会派上用场:)
  • 我已经取得了一些进展 - 似乎是使用 .seek() 和 .tell() 的代码行。将这些注释掉将正确上传文件,内容完好无损。现在来了解如何修复它(或使用其他方法来测量文件长度):)
  • 好吧,我没有检查,但我认为 tell 是在计算长度时将文件指针从 0 放到末尾 - 正如我建议的那样,只需用 seek 将指针放回去。
  • 另一种方式...不要直接检查文件大小,而是将 Flask 的最大请求大小设置为您的最大文件大小 - 因此会自动检查太大的文件。 flask.palletsprojects.com/en/1.1.x/config/#MAX_CONTENT_LENGTH
  • 在设置长度变量后添加另一个 .seek(0) 解决了我的问题。非常感谢!
【解决方案2】:

我遇到了同样的问题,上面推荐的修复方法帮助了我!据我了解,这是因为当您获取文件大小时,文件指针位于文件末尾。只需使用另一个 file_to_upload.seek(0) 撤消此操作即可。

为了清楚起见,您的代码现在应该如下所示:

file_path = upload_path + "/" + file_name
file_to_upload.seek(0)
file_to_upload.save(file_path) 

【讨论】:

    猜你喜欢
    • 2021-06-02
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 1970-01-01
    相关资源
    最近更新 更多