Dynamically Uploading A File In Background With Javascript
Solution 1:
You can not copy a file input element and set/keep its value. It is for security reasons. There is no reason why you need to create a new form. Just append an iframe to the page, set the target of form to the iframe name and submit the original form.
Solution 2:
I have looking for the same problem and I think, I have found an solution, which will work for Firefox and Chrome and may be on IE 10 and above ( here I need some morr testing )
The solution is a little bit ugly because I use a frameset. But this is the only solution I have found so far.
The use case is: We have a website with an product catalog, the editor can upload videos for each product.
The upload of the video need a long time, so I have look for an solution, where after you have chosen a video an start the upload, you can navigate to an other product and upload an other file without to wait until the download of the first is complete.
The test is based on some other work:
https://stackoverflow.com/a/1186309/2248340https://stackoverflow.com/a/105074/2248340
How it works:
If you press submit, all you form data will be placed in an object. in this object is also the selected file list.
This object will push in an array requests in the upload frame.
here runs the watchdog and look if there are new requests ( status = 0 ) If it found one a new upload is started.
Here is my test project to try it:
The frameset:
<!DOCTYPE html><html><head><metacharset="UTF-8"><title>Insert title here</title></head><framesetrows="*,100"><frameid="start"name="start"src="start.html"><frameid="upload"name="upload"src="frame.html"></frameset><noframes><body><ahref="start.html">please use this</a></body></noframes></html>
start.html
<!DOCTYPE html><html><head><metacharset="UTF-8"><title>Start</title><scriptsrc="../js/jquery-1.11.3.min.js" ></script><script>var files;
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
varUploadRequest=function(f)
{
var o= {};
o['guid']=guid();
o['action']=$('form').attr('action');
o['files']=files;
o['values']=$('form').serializeObject();
o['status']=0;
return o;
}
functionfileSelect( e){
files=e.target.files;
returnfalse;
}
</script></head><body><formid="test"action="phpinfo.php"><inputname="test" ><inputtype="hidden"name="h1"value="2"><inputtype="file"name="uploadfile"onchange="fileSelect(event)"><inputtype="submit"value="upload‚" ></form><script>var olddogcounter=localStorage['uploadwatchdog'];
var check=false;
functionguid() {
functions4() {
returnMath.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
returns4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
$(function() {
$('#test').submit(function() {
var request=newUploadRequest();
parent.upload.requests.push(request);
returnfalse;
});
});
</script><ahref="test.html" >test</a></body></html>
and the upload frame:
<!DOCTYPE html><html><head><metacharset="UTF-8"><title>frame</title></head><body><h1>frame</h1><iframeid="response"width="100%"height="200"></iframe><script>var requests=newArray();
var counter=0;
functionwatchdog()
{
for(var i=0; i<requests.length; i++)
{
var request=requests[i];
if(request.status==0)
{
alert("watchdog :"+dump(request));
request.status=1;
uploadFile(request);
}
}
}
functionuploadFile(request)
{
var url = request.action;
var xhr = newXMLHttpRequest();
var fd = newFormData();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
iframe=document.getElementById("response");
iframe.src="data:text/html;charset=utf-8," + escape(xhr.responseText);
}
};
if(request.files.length>1)
{
for(var i=0; i<request.files.length;i++)
{
var file=request.files[i];
fd.append("upload_file[]", file);
}
}
else
{
var file=request.files[0];
fd.append("upload_file",file );
}
for( var key in request.values)
{
fd.append(key,request.values[key] );
}
xhr.send(fd);
}
window.setInterval(watchdog,2000);
</script></body></html>
The solution is not complete, but I think is an good starting point.
ToDo: - Show name of uploads in a list - after upload remove request from array requests - show progess bar for upload - some error handling
Post a Comment for "Dynamically Uploading A File In Background With Javascript"