0

I'm trying to upload a PDF document using AJAX, but it keeps on failing with an unknown error. What am I doing wrong?

HTML File:

<form id="document">
    <p>
        Title<br>
        <input type="text" name="name" size="30">
    </p>
    <p>
        Please specify a file, or a set of files:<br>
        <input type="file" name="datafile" size="40">
    </p>
    <div>
        <input id="submit-button" type="button" value="Send">
    </div>
</form>

<script src="jquery.js"></script>
<script>
    $(document).ready(function(){
        $('#submit-button').click(function() {
            $.ajax({
                type: "POST",
                dataType: "JSON",
                url: "upload_document.php",
                data:  $("#document").serialize(),
                success : function(data){
                    alert(data.message);
                }, error : function(data) {
                    alert(data.message);
                }
            });
        });
    });
</script>

PHP File (upload_document.php)

<?php

header("Access-Control-Allow-Origin: *");

try {
    $id = "[RANDOM_GENERATED_GUID]";

    $targetDir = "../../../../modules/sites/documents/";
    if (!is_dir($targetDir)) {
        if (!mkdir($targetDir, 0777, true)) {
            throw new Exception("Unable to upload your document. We were unable to create the required directories");
        }
    }

    $targetFile = $targetDir . $id . ".pdf";
    $fileType = pathinfo($targetFile, PATHINFO_EXTENSION);

    if (file_exists($targetFile)) {
        throw new Exception("Unable to upload your document. The file already exists");
    }

    if ($_FILES["datafile"]["size"] > 2000000) {
        throw new Exception("Unable to upload your document. The file is to large (Maximum of 2MB)");
    }

    if ($fileType != "pdf") {
        throw new Exception("Unable to upload your document. Only PDF documents can be uploaded");
    }

    if (!move_uploaded_file($_FILES["datafile"]["tmp_name"], $targetFile)) {
        //Keeps failing here with error code 0
        throw new Exception("Unable to upload your document. There was an error uploading the file");
    }

    echo json_encode(array(
        "error" => false,
        "message" => "Your document was successfully uploaded"
    ));
} catch (Exception $ex) {
    echo json_encode(array(
        "error" => true,
        "message" => $ex->getMessage()
    ));
}

I also checked on the server, and the directory is being created successfully. Thanks for the help!

Edit
This exact same PHP script works if I set the action on the form, and use a submit button. The only reason I want to use AJAX, is to display a modal dialog after receiving a response

  • One problem that I see that you are getting $fileType from name that you generated and not from the file you are uploading, it should be like this `$fileType = pathinfo($_FILES["datafile"]["tmp_name"], PATHINFO_EXTENSION);` – kunicmarko20 Mar 26 '16 at 21:54
  • Thanks, I'll try that. But I also forgot to mention, that this works perfectly if I use a form, set the action and use a submit button –  Mar 26 '16 at 21:55
  • You can't serialize a file this way. Browser security/sandboxing won't permit it. You have to use some other solution, possibly something using an iframe. See this [link](http://stackoverflow.com/a/4545089/1233305) – David784 Mar 26 '16 at 23:46

1 Answers1

0

When you start using AJAX POST, the posted parameter should be looked for in $_POST instead of $_FILES.

This is because $_FILES is a cache for files uploaded through multipart post. Since you have serialized it and sent using AJAX, PHP parses the JSON and put everything inside $_POST

Look here for an example

Community
  • 1
  • 1
Yushi Sun
  • 11
  • 3
  • Thanks for the response. I've tried replacing the $_FILES with $_POST, but I'm still getting the same error –  Mar 26 '16 at 22:38
  • @HenryJooste Can you try bisecting your PHP code to see exactly which line caused the problem? – Yushi Sun Mar 26 '16 at 22:41
  • Yes, I've already done that. It fails at the `move_uploaded_file` call. So I'm sure it gets the file, because it passes the PDF file extension check –  Mar 26 '16 at 22:44