You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Ajax向Flask发送图片?现有方法返回None求解决

问题描述

我试了好几种方法,但找到的相关答案大多是2013年的,有人说只在jQuery 1.6版本生效,我拿不准。下面是我试过的代码:

尝试的HTML代码
<div class="form-group d-flex justify-content-center p-2 w-100" class="create-post-forms">
            
            <fieldset>
              <label id="add_photo_button" for="uploadImage" class="w-50 me-1"> <div class="btn btn-primary w-100 border-0 ">Add Photo</div> </label>
              <input type="file" id="upload_file" name="postphoto" style="display: none">
          </fieldset>

</form>
JavaScript/Ajax代码
var photo = new FormData($('#post_info')[0]);
console.log(photo)

// 我也试过 photo.get("myPhoto")

$.ajax({
  type: "POST",
  dataType: "json",
  url: "/make_post_ajax",
  contentType: 'application/json; charset=utf-8',
  data: JSON.stringify({ myPhoto : photo }),
  success: function(data) {
      console.log(data)
  }
});
Flask代码
photo = request.files.get('myPhoto')
结果
None

请问如何正确实现通过Ajax向Flask发送图片?


问题根源

你现在的写法有两个核心问题:

  1. FormData不能用JSON.stringify序列化:FormData是二进制表单数据对象,JSON只能序列化普通对象,直接转JSON会丢失文件数据,导致后端拿不到。
  2. Ajax请求配置错误:上传文件时不能设置contentType: 'application/json',应该让jQuery自动设置正确的multipart/form-data请求头,同时要加上processData: false(禁止jQuery处理FormData,避免自动转成urlencoded格式)。

另外HTML里还有两个小问题:div标签写了两个class属性,需要合并;label的for属性是uploadImage,但文件输入框的id是upload_file,不匹配会导致点击按钮无法触发文件选择。

修正后的代码

1. 修正HTML

<form id="post_info" class="form-group d-flex justify-content-center p-2 w-100 create-post-forms">
  <fieldset>
    <!-- 统一label的for和input的id -->
    <label id="add_photo_button" for="upload_file" class="w-50 me-1">
      <div class="btn btn-primary w-100 border-0">Add Photo</div>
    </label>
    <input type="file" id="upload_file" name="postphoto" style="display: none">
  </fieldset>
</form>
  • 给表单加上id="post_info"(匹配你之前FormData的选择器)
  • 合并div的重复class属性
  • 修正label与input的关联关系

2. 修正JavaScript/Ajax

// 基于表单创建FormData,自动包含文件输入
var formData = new FormData($('#post_info')[0]);

// 给按钮添加点击触发上传的逻辑(示例)
$('#add_photo_button').on('change', function() {
  $.ajax({
    type: "POST",
    url: "/make_post_ajax",
    // 不要手动设置contentType,让jQuery自动处理
    contentType: false,
    // 禁止处理FormData,避免转码丢失文件
    processData: false,
    data: formData,
    success: function(data) {
      console.log(data);
    },
    error: function(xhr) {
      console.error('上传失败:', xhr.responseText);
    }
  });
});
  • 直接使用表单生成的FormData,无需额外包装
  • 关键设置contentType: false和processData: false
  • 添加了文件选择后的触发逻辑(你可以根据实际场景调整触发时机)

3. 修正Flask后端

from flask import request, jsonify

@app.route('/make_post_ajax', methods=['POST'])
def make_post_ajax():
    # 键名要和input的name属性一致,即"postphoto"
    photo = request.files.get('postphoto')
    if photo and photo.filename:
        # 示例:保存文件到服务器
        # photo.save(f'./uploads/{photo.filename}')
        return jsonify({'status': 'success', 'message': '文件上传成功'})
    return jsonify({'status': 'error', 'message': '未获取到文件'}), 400
  • 注意request.files.get的参数是文件输入框的name属性值,而非自定义的myPhoto

验证步骤

  1. 点击"Add Photo"按钮选择图片
  2. 触发Ajax请求(上述代码已绑定文件选择后的上传逻辑)
  3. 后端即可正确拿到文件对象,不会返回None

内容的提问来源于stack exchange,提问作者corieleclair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:45:27