Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
110
rated 0 times [  114] [ 4]  / answers: 1 / hits: 24691  / 12 Years ago, sun, may 6, 2012, 12:00:00

I know there are a lot of similar questions, but I still haven't found a solution for my problem.
I'm trying to upload a file with XMLHttpRequest, so I developed the code below:



var sendFiles = function(url,onload,onerror,file,headers){
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp'),
upload = xhr.upload;
API.addEvent(xhr,'readystatechange',function(){
if(xhr.readyState==4)
if((xhr.status>=200 && xhr.status<300) || xhr.status==304){
this.response = this.response || this.responseText;
onload.call(xhr);
}else onerror.call(xhr);
});
xhr.open('POST',url,true);
for(var n=0;n<headers.length;n++)
xhr.setRequestHeader(headers[n]);
xhr.send(file);
return xhr;
};


And the PHP-side script is:



<?php
header('Content-type: text/html;charset=ISO-8859-1');
$status = 0;
if(@copy($_FILES['file']['tmp_name'],'test\' . $_FILES['file']['name']))
$status = 1;
else
$err = '0';
echo '{
status: ' . $status . '
}';
?>;


But the var $_FILES['file'] seems to be empty, which means that the file isn't being sent to the server.
Then i decided to use the FormData Object, in the code below



var sendFiles = function(url,onload,onerror,file,headers){
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp'),
upload = xhr.upload,
formData = new FormData();
formData.append('file',file);
API.addEvent(xhr,'readystatechange',function(){
if(xhr.readyState==4)
if((xhr.status>=200 && xhr.status<300) || xhr.status==304){
this.response = this.response || this.responseText;
onload.call(xhr);
}else onerror.call(xhr);
});
xhr.open('POST',url,true);
for(var n=0;n<headers.length;n++)
xhr.setRequestHeader(headers[n]);
xhr.send(formData);
return xhr;
};


And it worked, but only with file sizes low to about 8mb. When I try sending a file that has more than 8mb of size, the var $_FILES['file'] becomes empty again



NOTE: the 'file' var corresponds to something like document.getElementsById('fileInput').files[0];


More From » ajax

 Answers
42

To avoid the post_max_size limitation problem... but also out of memory problems on both sides :



On the client side




  • use PUT instead of POST :



    xhr.open(put, upload.php, true);


  • add custom headers to specify original FileName and FileSize :



    xhr.setRequestHeader(X-File-Name, file.name);

    xhr.setRequestHeader(X-File-Size, file.size);


  • use the File object directly in your XHR send method :



    xhr.send(file);



    Please note that the File object can be obtained directly via the “files” property of your input[type=file] DOM object




On the server side




  • read the custom headers via $_SERVER :



    $filename = $_SERVER['HTTP_X_FILE_NAME'];

    $filesize = $_SERVER['HTTP_X_FILE_SIZE'];


  • read file data using php://input :



    $in = fopen('php://input','r');




You'll then be able to send very big files (1GB or more) without any limitation!!!



This code works for FireFox 4+, Chrome 6+, IE10+


[#85741] Saturday, May 5, 2012, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
denver

Total Points: 232
Total Questions: 111
Total Answers: 103

Location: South Korea
Member since Sat, Oct 2, 2021
3 Years ago
;