使用包含文件的JSON对象向PHP发送AJAX Post

使用包含文件的JSON对象向PHP发送AJAX Post,php,ajax,post,file-upload,Php,Ajax,Post,File Upload,我试图将一个文件附加到一封电子邮件中,该电子邮件位于发布到PHP脚本的JSON对象的内部 发布的JSON显示为: { data:{ "sendto":"sendto@example.com", "name":"John Smith", "contem":"john.smith@example.com", "mess":"This is a test", "subj":"Test" }, file:{

我试图将一个文件附加到一封电子邮件中,该电子邮件位于发布到PHP脚本的JSON对象的内部

发布的JSON显示为:

{  
   data:{  
      "sendto":"sendto@example.com",
      "name":"John Smith",
      "contem":"john.smith@example.com",
      "mess":"This is a test",
      "subj":"Test"
   },
   file:{  
      "webkitRelativePath":"",
      "lastModified":1389280265000,
      "lastModifiedDate":"2014-01-09T15:11:05.000Z",
      "name":"test.pdf",
      "type":"application/pdf",
      "size":6437
   }
}
我的PHP可以很好地处理所有“数据”属性,但是当我尝试检查文件时,我得到:

Notice:  Undefined index: file in My\Website\Location\script.php on line 20
第20行是:

$file = $_FILES['file'];
该索引是否因为在JSON对象中而未定义?

我也试过:

$file = $_FILES[json_decode(stripslashes($_POST['file']), true)];
考虑到文件位于JSON对象中,首先需要对其进行解码。然而,这返回了:

Warning:  Illegal offset type in My\Website\Location\script.php on line 20
我认为非法偏移量的问题与试图将$\u文件设置为JSON对象有关,是吗?

当我试图简单地将$\u POST['file']设置到$\u FILES数组中时:

$file = $_FILES[$_POST['file']];
我收到:

Notice:  Undefined index: {"webkitRelativePath":"","lastModified":1389280265000,"lastModifiedDate":"2014-01-09T15:11:05.000Z","name":"test.pdf","type":"application/pdf","size":6437} in My\Website\Location\script.php on line 20
将上载的文件显示为JSON对象

我在这里错过了什么?如何从我的AJAX帖子中获取上传的文件?

回答

正如关于multiform/form数据内容类型所述,我更改了发送表单数据的方式

而不是使用包含文件的对象:

var d = new FormData();
var data = {};
data.sendto = 'sendto@example.com';
data.name = $('#puName').val();
data.contem = $('#puEmail').val();
data.mess = $('#puMess').val();
data.subj = 'User Permissions';
d.append('data', JSON.stringify(data));
$.each($('#puFile')[0].files, function(i, file) {
     d.append('file-'+i, file);
});
sendEmail(d);
我直接向PHP脚本发送了一个FormData对象

function sendEmail(d){
    $.ajax({
        url: "script.php",
        data: d,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function () {
            alert("Cool");
        },
        error: function (e) {
            alert("Not Cool");
        }
    });
}
FormData由我的数据的JSON对象和所选文件组成

PHP然后读取表单数据,如下所示:

$data = json_decode(stripslashes($_POST['data']), true);
$file = $_FILES['file-0'];

现在,我的电子邮件已正确发送。

$\u文件
superglobal仅在为帖子设置了
multipart/form data
内容类型时才会创建,内容类型将包括正在发布的实际文件,而不是该文件的本地引用。相反,您发送的是一个JSON请求(希望带有适当的
应用程序/JSON
内容类型)。这不会填充
$\u文件
。除非您的接收脚本能够获取提供的路径信息并访问相关文件,否则您的发布脚本实际上需要将文件作为发布的一部分发送


通过AJAX上传文件最好使用特定的AJAX上传库来处理,这些库基本上利用了一些变通方法,使您无法在浏览器中以本机方式异步发布文件。

您尝试过类似的方法吗-

将json代码复制到一个变量中,比如说“a”,然后对其进行解码,即json_decode(a),然后
->file

您的JSON格式不正确。测试是在感谢-所以我应该1,而不是用我的表单组件创建一个对象。将我的整个表单提交到PHP脚本,然后2。将我的AJAX帖子中的contentType更改为“multipart/form data”?这可能是关于非同步文件上载的权威SO帖子-阅读前几个答案,了解您尝试执行的操作的重要注意事项。这个答案让我走上了正确的道路。请参见上文,了解为使其正常工作所做的更改。