简体   繁体   中英

AJAX Post to PHP with JSON Object containing a File

I'm trying to attach a file to an email that is inside of a JSON object being posted to my PHP script.

The posted JSON appears as:

{  
   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
   }
}

My PHP handles all of the "data" attributes just fine, but when I try to check for the file, I get:

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

And Line 20 is:

$file = $_FILES['file'];

Is this index undefined because it's within a JSON object?

I've also tried:

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

Thinking since the file is within a JSON object, it first needs decoded. However, this returned:

Warning:  Illegal offset type in My\Website\Location\script.php on line 20

I think the issue for the illegal offset had something to do with trying to set $_FILES to a JSON object, yes?

When I try to simply set the $_POST['file'] into the $_FILES array:

$file = $_FILES[$_POST['file']];

I receive:

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

Showing the uploaded file as a JSON object.

What am I missing here? How can I get the uploaded file from my AJAX post?

ANSWER

As noted about the multiform/form-data content type, I changed the way I sent the form data.

Rather than using an object with a file inside of it:

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);

I sent a FormData object directly to the PHP script.

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");
        }
    });
}

The FormData was made of an JSON object for my data, and the selected File.

PHP then read the form data like:

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

Now my email is sending correctly.

$_FILES superglobal will only be created when multipart/form-data content-type is set for the POST and would include the actual file being POSTed, not a local reference to that file. Instead you are sending a JSON request (hopefully with an appropriate application/json content-type). This is not going to populate $_FILES . Unless your receiving script has the ability to take the path information provided and access the file in question, your POSTing script will actually need to send the file as part of the POST.

Uploading files via AJAX is best handled using specific AJAX upload libraries that are meant to do this, which basically utilize workarounds to the fact that you really can't POST a file asynchronously natively in browsers.

Have you tried something like this -

Copy the json code in a variable say 'a' and then, decode it ie json_decode(a), then a->file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM