I've been trying to create a non-flash upload panel which also shows a progress bar. On our server we have PHP 5.3 (cannot upgrade to 5.4 for now, so the new upload progress feature cannot be used => http://php.net/manual/en/session.upload-progress.php). We cannot use flash based solutions, extensions or similar.
Hence I've tried using an XMLHttpRequest combined with AJAX. The problem here is that I've only achieved partial success.
I've managed to upload and save on the server a file of about 380 MB, however, when trying with a larger file like 4 GB, it won't be saved on the server (if I check with Firebug at one point it would say "POST aborted").
Another strange thing is that with the same file the xhr.upload.loaded starts with the same dimension of xhr.upload.total and starts counting from there.
Does anyone know how to solve this problem or has an alternative solution?
The client code is:
<script type="application/javascript" src="jquery.js"></script>
<script type="application/javascript">
function uploadToServer()
{
fileField = document.getElementById("uploadedFile");
var fileToUpload = fileField.files[0];
var xhr = new XMLHttpRequest();
var uploadStatus = xhr.upload;
uploadStatus.addEventListener("progress", function (ev) {
if (ev.lengthComputable) {
$("#uploadPercentage").html((ev.loaded / ev.total) * 100 + "%");
}
}, false);
uploadStatus.addEventListener("error", function (ev) {$("#error").html(ev)}, false);
uploadStatus.addEventListener("load", function (ev) {$("#error").html("APPOSTO!")}, false);
xhr.open(
"POST",
"serverUpload.php",
true
);
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", fileToUpload.fileName);
xhr.setRequestHeader("X-File-Size", fileToUpload.fileSize);
xhr.setRequestHeader("X-File-Type", fileToUpload.type);
//xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(fileToUpload);
}
$(function(){
$("#uploadButton").click(uploadToServer);
});
</script>
HTML part:
<form action="" name="uploadForm" method="post" enctype="multipart/form-data">
<input id="uploadedFile" name="fileField" type="file" multiple />
<input id="uploadButton" type="button" value="Upload!">
</form>
<div id="uploadPercentage"></div>
<div id="error"></div>
Server side code:
<?php
$path = "./";
$filename = $_SERVER['HTTP_X_FILE_NAME'];
$filesize = $_SERVER['CONTENT_LENGTH'];
$file = "log.txt";
$fo= fopen($file, "w");
fwrite($fo, $path . PHP_EOL);
fwrite($fo, $filename . PHP_EOL);
fwrite($fo, $filesize . PHP_EOL);
fwrite($fo, $path . $filename . PHP_EOL);
file_put_contents($path . $filename,
file_get_contents('php://input')
);
?>
There are limits associated with the web server that can't be changed by PHP. Example, their is a default max post request size of 30MB in IIS...there is also a max timeout which you may be hitting. Has nothing to do with size, but how long your post request is taking...ie, how long its taking for the file submit. Both settings can be constrained by IIS or Apache.