通过jQuery和FormData进行的Ajax POST请求 - PHP中的$_POST为空

9

我希望使用jQuery和FormData通过ajax将图片上传到服务器。

我的jQuery代码如下:

var formData = new FormData("form")[0];
  var fileName = $("#InputLogo")[0].files[0].name;

  $.ajax ( {
      url : 'upload.php',
      type : 'POST',
      data : { "data" : formData, "fileName" : fileName },
      processData : false,
      success : function(data) {
          console.log(data);
          alert(data);
      }
  });

当用户选择上传新文件时,将调用此代码。
我的服务器后端是 PHP,并且它会按照以下方式处理请求。
$data = $_POST['data'];
$fileName = $_POST['fileName'];
$fp = fopen('/img/'.$fileName, 'w');
fwrite($fp, $data);
fclose($fp);
$returnData = array("data" => $data);
print_r($_POST);

发出了POST请求,但$_POST为空。

我尝试过搜索解决方案,但没有找到确切的解决方法。

任何建议都将不胜感激。

编辑:以下是HTML表单

<form id=card-form" method="post" action="" >
      <div class="form-group">
    <label for="InputName">Name of the Company</label>
    <input type="text" class="form-control" id="InputName" placeholder="Enter a name">
    </div>
    <div class="form-group">
    <label for="InputEmail">Email</label>
    <input type="email" class="form-control" id="InputEmail" placeholder="Enter email">
    </div>
    <div class="form-group">
    <label for="InputLogo">Choose a company logo</label>
    <input type="file" id="InputLogo" accept="image/*">
    <p class="help-block">For good visibility, please limit the image to 200 x 200 px</p>
    </div>
    <button type="submit" class="btn btn-default">Submit</button>
  </form>

你能否也发布一下你表单的HTML代码,以确保那里面的所有内容都是正确的。 - AgnosticDev
1
你想在jQuery文档中查找processData选项的作用... - CBroe
@AgnosticDev 我已经添加了表单HTML。 - Pankaj Bhambhani
@CBroe 我在创建表单时参考了这个链接。我认为 processData 不是问题所在。 - Pankaj Bhambhani
5个回答

15
FormData() 构造函数 不是选择器引擎,也不代表类似于数组的集合,因此 var formData 可能等于 undefined
要使用它,您需要先找到 <form> 并将其传递给构造函数:
var form = $('form')[0];
var formData = new FormData(form);
如果<input type="file">位于<form>内部,它应该已经包含在formData中了。但如果不是这样,你也可以使用.append()方法添加它:
var inputLogo = $("#InputLogo")[0];
formData.append(inputLogo.name, inputLogo.files[0]);

formData设置为发送的data,告诉jQuery不要为其假定contentType

// ...
    data : formData,
    contentType : false,
    processData : false,
// ...

然后,在PHP的$_FILES集合中应该可以使用fileSize

$fileName = $_FILES['inputLogo']['name'];

1
我已经更正了 FormData 构造函数,并尝试从 $_FILES 中获取文件名,就像你提到的那样。但是它还没有起作用。我尝试打印 $_FILES 的转储。它也是空的。$_GET$_REQUEST 也是如此。 - Pankaj Bhambhani
对我来说也是一样的..你找到解决方案了吗? - Manuel

8

我知道这是一篇旧帖子,但在解决类似问题时我偶然发现了它,发现没有回复指出这个问题,所以我在这里回复,以防其他人遇到相同的情况。

事实证明,正如另一个StackOverflow帖子中所记录的:

如果input标签没有名称,表单数据是否仍会传输?

如果文件输入元素没有非空名称属性,则该元素中的任何数据都不会在请求中发送。

因此,你的输入元素应该如下所示:

<input type="file" id="InputLogo" accept="image/*">

应该是:
<input type="file" id="InputLogo" accept="image/*" name="yourfieldnamehere">

否则该文件将不会随表单数据一起发送。

6
我也尝试了很多以下方法:

var formData = new FormData("form")[0];
var formData = new FormData("form");
var formData = new FormData($('form-id'));
var formData = new FormData(this);

以上方法都对我无效。 但最后,我使用了一种JavaScript的getElementById方法,它完美地解决了问题。

formdata = new FormData(document.getElementById('form_id'))

通常在请求头中,您会发现像下面给出的加密文本: multipart/form-data; boundary=----WebKitFormBoundaryUuVvGDydAdTf3Bmp 当您尝试警报表单数据时,它将显示[object formdata]。这意味着formdata函数工作正常。
当您返回$_POST、$_REQUEST或$_FILES的值并且如果为空,则意味着formdata无法访问提供的表单元素。因此,首先必须确认formdata能否访问表单元素,然后再尝试其他可能性。

4
由于您需要提供“#” ID选择器,因此您需要使用以下代码: var formData = new FormData($('#form-id')[0]); - lapint

4

在使用ajax的formData时,有几件事情需要考虑。你可以使用FormData的append()方法向其中添加数据。

试试这个...

 var formData = new FormData("form")[0];
 formData.append("fileName",$("#InputLogo")[0].files[0].name);

 $.ajax ( {
   url : 'upload.php',
   type : 'POST',
   data : formData,
   processData: false,  // tell jQuery not to process the data
   contentType: false,   // tell jQuery not to set contentType
   success : function(data) {
      console.log(data);
      alert(data);
   }
});

参考资料

需要翻译的内容已经包含在了参考资料中,链接请见上方。

是的,我正在遵循你提到的相同参考。但似乎还没有起作用。 - Pankaj Bhambhani
没有设置 contentType,jQuery 会将数据发送为原始数据。 - Vikas Kandari

0

一个问题是,除非您使用一些HTML5的优势,否则通过Ajax上传文件将无法正常工作。

这里有一篇很好的文章描述了它: 如何异步上传文件?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接