Skip to content Skip to sidebar Skip to footer

Dynamically Uploading A File In Background With JavaScript

I'm trying to upload files in the background. I am not able to use any frameworks so I have to do manually. The page already contains a form, and the file input fields are located

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/2248340 https://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>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<frameset rows="*,100">
    <frame id="start" name="start" src="start.html">
    <frame id="upload" name="upload" src="frame.html">
</frameset>
<noframes>
    <body>
        <a href="start.html">please use this</a>
    </body>
</noframes>
</html>

start.html

<!DOCTYPE html>
<html>
   <head>
    <meta charset="UTF-8">
    <title>Start</title>
    <script src="../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;
    };

    var UploadRequest=function(f)
    {
        var o= {};
        o['guid']=guid();
        o['action']=$('form').attr('action');
        o['files']=files;
        o['values']=$('form').serializeObject();
        o['status']=0;
        return o;
    }

    function fileSelect( e){
        files=e.target.files;
        return false;
    }

    </script>
  </head>
  <body>
      <form id="test" action="phpinfo.php">
      <input  name="test" >
      <input type="hidden"  name="h1" value="2">
      <input type="file"  name="uploadfile" onchange="fileSelect(event)">
      <input type="submit" value="upload‚" > 
      </form>
      <script>
      var olddogcounter=localStorage['uploadwatchdog'];
      var check=false;
      function guid() {
          function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
              .toString(16)
              .substring(1);
          }
          return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
            s4() + '-' + s4() + s4() + s4();
        }

      $(function() {
            $('#test').submit(function() {
                var request=new UploadRequest();
                parent.upload.requests.push(request);  
                return false;
            });
        });
      </script>
      <a href="test.html" >test</a>
  </body>
</html>

and the upload frame:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>frame</title>

</head>
<body>
    <h1>frame</h1>

    <iframe id="response" width="100%" height="200"></iframe>

    <script>
      var requests=new Array();
      var counter=0;
      function watchdog()
      {
          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); 
              }
          }
      }

      function uploadFile(request)
      {
        var url = request.action;
        var xhr = new XMLHttpRequest();
        var fd = new FormData();
        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"