Динамическая загрузка файла в фоновом режиме с помощью JavaScript - PullRequest
0 голосов
/ 08 мая 2011

Я пытаюсь загрузить файлы в фоновом режиме.Я не могу использовать какие-либо рамки, поэтому я должен сделать это вручную.Страница уже содержит форму, и поля ввода файла расположены внутри этой формы, поэтому я не могу встроить форму в форму, поэтому мне нужно переместить ввод файла вокруг.

Проблема с кодомЯ использую то, что он, кажется, на самом деле не подчиняется, я вообще не вижу сетевой активности.Кто-нибудь может заметить здесь что-то не так?

<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;
}

Ответы [ 2 ]

3 голосов
/ 08 мая 2011

Нельзя скопировать элемент ввода файла и установить / сохранить его значение.Это из соображений безопасности.Нет причин, по которым вам нужно создавать новую форму.Просто добавьте iframe на страницу, установите цель формы на имя iframe и отправьте оригинальную форму.

1 голос
/ 13 ноября 2015

Я искал ту же проблему, и я думаю, я нашел решение, которое будет работать для Firefox и Chrome и может быть на IE 10 и выше (здесь мне нужно немного больше тестировать)

Решение немного некрасиво, потому что я использую набор фреймов.Но это единственное решение, которое я нашел до сих пор.

Вариант использования: у нас есть веб-сайт с каталогом продуктов, редактор может загружать видео для каждого продукта.

Загрузка видео требует длительного времени, поэтому я ищурешение, при котором после того, как вы выбрали видео для начала загрузки, вы можете перейти к другому продукту и загрузить другой файл, не дожидаясь завершения загрузки первого.

Тест основан нанекоторые другие работы:

https://stackoverflow.com/a/1186309/2248340 https://stackoverflow.com/a/105074/2248340

Как это работает:

Если вы нажмете "Отправить", все данные формы будут помещены в объект,в этом объекте также выбран список файлов.

Этот объект будет выдвигать запросы массива в кадре загрузки.

здесь запускает сторожевой таймер и проверяет наличие новых запросов (status = 0) Если он нашел один, новая загрузка начата.

Вот мой тестовый проект, чтобы попробовать его:

Набор фреймов:

<!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>

и кадр загрузки:

<!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>

Решение не завершено, но я думаю, что это хорошая отправная точка.

ToDo: - Показать название загрузки вlist - после загрузки удалить запрос из массива запросов - показать панель progess для загрузки - некоторая обработка ошибок

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...