http - Dynamically uploading a file in background with JavaScript - Stack Overflow

I'm trying to upload files in the background. I am not able to use any frameworks so I have to do

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 within that form, so I can't embed a form in a form so I need to move the file input around.

The problem with the code I'm using is that it doesn't seem to actually submit, I don't see any network activity at all. Can anyone spot anything wrong here?

<form>
...
  <input id="photo-file-input" type="file"/>
  <button type="button" onClick="uploadBackground('photo-file-input');">Upload</button>
....
</form>

function uploadBackground(fileInputId)
{
    var iframe = createIframe('TEST');
    var form = createUploadForm('TEST', 'upload.php');
    var fileInput = document.getElementById(fileInputId);
    var fileInputParent = fileInput.parent;

    //move file input into generated form
    form.appendChild(fileInput);
    form.submit();

    iframe.onload = function()
    {
        alert('file was uploaded');
        //put the file input back where it was
        fileInputParent.appendChild(fileInput);

        //clean up generated elements
        iframe.parent.removeChild(iframe);
        form.parent.removeChild(form);
    }
}


function createUploadForm(target, action)
{
    var form = document.createElement('form');

    form.display = 'none';
    form.target = target;
    form.action = action;
    form.method = 'POST';
    form.enctype = 'multipart/form-data';

    return form;
}

function createIframe(name)
{
    var iframe;

    try
    {
            iframe = document.createElement('<iframe name="' + name + '">');
    }
    catch (ex)
    {
            iframe = document.createElement('iframe');
            iframe.name = name;
    }

    return iframe;
}

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 within that form, so I can't embed a form in a form so I need to move the file input around.

The problem with the code I'm using is that it doesn't seem to actually submit, I don't see any network activity at all. Can anyone spot anything wrong here?

<form>
...
  <input id="photo-file-input" type="file"/>
  <button type="button" onClick="uploadBackground('photo-file-input');">Upload</button>
....
</form>

function uploadBackground(fileInputId)
{
    var iframe = createIframe('TEST');
    var form = createUploadForm('TEST', 'upload.php');
    var fileInput = document.getElementById(fileInputId);
    var fileInputParent = fileInput.parent;

    //move file input into generated form
    form.appendChild(fileInput);
    form.submit();

    iframe.onload = function()
    {
        alert('file was uploaded');
        //put the file input back where it was
        fileInputParent.appendChild(fileInput);

        //clean up generated elements
        iframe.parent.removeChild(iframe);
        form.parent.removeChild(form);
    }
}


function createUploadForm(target, action)
{
    var form = document.createElement('form');

    form.display = 'none';
    form.target = target;
    form.action = action;
    form.method = 'POST';
    form.enctype = 'multipart/form-data';

    return form;
}

function createIframe(name)
{
    var iframe;

    try
    {
            iframe = document.createElement('<iframe name="' + name + '">');
    }
    catch (ex)
    {
            iframe = document.createElement('iframe');
            iframe.name = name;
    }

    return iframe;
}
Share Improve this question asked May 7, 2011 at 21:43 ArturPhilibinArturPhilibin 9332 gold badges12 silver badges26 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

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.

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 plete.

The test is based on some other work:

https://stackoverflow./a/1186309/2248340 https://stackoverflow./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 plete, 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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745304669a4621638.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信