0

I have a blob object and some data need to be post to fileHandler.php

so I pack them into a FormData:

        console.log("start saving");
        var url1 = URL.createObjectURL(blob);
        var url2 = "data:application/octet-stream," + encodeURIComponent(JSON.stringify(dataPack));
        console.log(url1);
        console.log(url2);
        fd.append('realName', dataPack.name);
        fd.append("ans", JSON.stringify(dataPack.ans));
        fd.append("log", JSON.stringify(dataPack.log));
        fd.append("part", dataPack.part);
        fd.append('fileToUpload', blob);
        window.postData = fd;

and upload them via ajax:

    $.ajax({
        type: 'POST',
        url: '../php/fileHandler.php',
        data: postData,
        processData: false,
        contentType: false,
        success: function() {
            uploadSuccess();
        },
        error: function() {
            uploadFail();
        },
        progress: function(e) {
            console.log(e);
            //make sure we can compute the length
            if(e.lengthComputable) {
                //calculate the percentage loaded
                var pct = parseInt((e.loaded / e.total) * 100);

                //log percentage loaded
                $('#uploadProgress').width(pct+"%").text(pct+"%");
                console.log(pct);
            }
            //this usually happens when Content-Length isn't set
            else {
                console.warn('Content Length not reported!');
            }
        }
    }).done(function(data) {
        console.log(data);
        if(data ==="ok") {
            uploadSuccess();
        }
        else {
            uploadFail();
        }
    });

php file handler:

<?php
$target_dir = "uploads/";
$realName = trim($_POST['realName']);
$part = $_POST['part'];
$ans = json_decode($_POST['ans']);
$log = json_decode($_POST['log']);
$fileNameNoEx = $target_dir . $realName . "-" . $part ."-". time();
$target_file = $fileNameNoEx . ".mp3";
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);

// Check if file already exists
if (file_exists($target_file)) {
    echo "Sorry, file already exists.";
    $uploadOk = 0;
}

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
    echo "Sorry, your file was not uploaded.";

// if everything is ok, try to upload file
} else {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        //save files
        $f = fopen($fileNameNoEx.".txt", "w");
        fwrite($f, "Answer log:\n");
        foreach ($ans as $page => $val) {
            fwrite($f, "$page : $val\n");
        }
        fwrite($f, "\nPage switching event log:\n");
        foreach ($log as $l) {
            fwrite($f, "{$l->time}s  --->  {$l->page}\n");
        }
        fclose($f);
        echo "ok";
    } else {
        var_dump($ans);
        var_dump($log);
        var_dump($_POST);
        var_dump($_FILES);
        var_dump($target_file);
        echo "asdsad";
        echo "Sorry, there was an error uploading your file.";
    }
}

then strange things happen, sometimes uploading failed, and I when I try to upload again(in console, with the same data), browser keep logging:

NULL
NULL
array(0) {
}
array(0) {
}
string(24) "uploads/--1500100885.mp3"
asdsadSorry, there was an error uploading your file.

it seems that postData is empty? But when I check the postData in browser console:

> postData.get("fileToUpload")
File {name: "blob", lastModified: 1500101804839, lastModifiedDate: Sat Jul 15 2017 14:56:44 GMT+0800 (China Standard Time), webkitRelativePath: "", size: 12597888…}
> postData.get("realName")
"jjj"

why???? how can $_FILES[] and $_POST[] be emtpy?

This problem happens often when the file is very large.

Lixin Wei
  • 441
  • 5
  • 17
  • you call `window.postData = fd;` then use `data: postData,`, are you sure you are accessing that correctly? Depending on where the code is, `postData` may not be the value you expect due to scope – Wesley Smith Jul 15 '17 at 06:58
  • @DelightedD0D I've checked window.postData in console, it surely exists. – Lixin Wei Jul 15 '17 at 06:59
  • sure, but you're not using `window.postData` you're using just `postData` in this line: `data: postData,`. what happens if you use `data: window.postData,`? – Wesley Smith Jul 15 '17 at 07:00
  • Not sure it maters in your code, depends on where the code is placed, yours might be fine – Wesley Smith Jul 15 '17 at 07:02
  • @DelightedD0D I've change the `postData` to `window.postData`, and test the ajax again in console, but the problem still exists. – Lixin Wei Jul 15 '17 at 07:02
  • gotcha fair enough – Wesley Smith Jul 15 '17 at 07:03
  • what do `uploadSuccess()` and `uploadFail()` do exactly, do either of them modify `window.postData`? – Wesley Smith Jul 15 '17 at 07:09
  • @DelightedD0D No, they are just dealing with UI. – Lixin Wei Jul 15 '17 at 07:10
  • How is `window.postData = fd;` related to the ajax call positionally? are they in the same function? Is there any code between setting the value and using it in the ajax call? If so, does any of that code modify `window.postData`? – Wesley Smith Jul 15 '17 at 07:12
  • Also, if you add `console.log(postData);` right before the ajax call, does it also report an empty object when the php side reports the failure? – Wesley Smith Jul 15 '17 at 07:14
  • @DelightedD0D I add `console.log(postData.get("fileToUpload"));` right before `console.log(data);` It do return a file object. – Lixin Wei Jul 15 '17 at 07:19
  • And you're saying that it works for most request but fails for some? – Wesley Smith Jul 15 '17 at 09:06

1 Answers1

1

PHP has a maximum post size, try to increase it: Increasing the maximum post size

If PHP didn't have this limit I could send an infinitely large POST to your web server until either it runs out of disk or RAM.

Hannes Landeholm
  • 1,525
  • 2
  • 17
  • 32