2012-12-14 17 views
8

Come posso recuperare $_FILES in PHP quando carico tramite un Web Worker? Quando ho cercato di usare FormData, ho ottenuto il seguente errore:Come caricare file in Web Worker quando FormData non è definito

Error: FormData is not defined

Questo è il mio codice:

function uploadFile(blobFile, fileName, filePart, totalChunks) { 
    //if I try to put this 
    //var formData = new FormData(); //it does not work 
    var xhr = new XMLHttpRequest();     
    xhr.open("POST", "upload.php"+"?"+"file="+fileName + filePart, true); 
    xhr.onload = function(e) {}; 
    xhr.send(blobFile); 
} 

Quindi, in upload.php come faccio per ottenere il percorso tmp da $_FILES? Solo nel caso, ho anche mostrare la pagina fa riferimento il lavoratore Web:

<form id="fileuploader" enctype="multipart/form-data" method="post" action="upload.php"> 
    <label for="fileToUpload">Select Files to Upload</label><br /> 
    <input type="file" name="fileToUpload[]" multiple="" id="fileToUpload" onchange="fileList();"/><br /> 
    <input type="button" onclick="sendRequest();" value="Upload" /> 
    <!-- a place for File Listing --> 
    <div id="fileList"></div>   
</form> 
<script type="text/javascript"> 
function sendRequest() { 
    var worker = new Worker("fileupload.js"); 
    worker.onmessage = function(e) { 
     alert(e.data); 
    } 
    var file = document.getElementById('fileToUpload'); 
    for(var i = 0; i < file.files.length; i++) { 
     worker.postMessage(file.files[i]); 
    } 
} 
+1

L'oggetto formdata bisogno di accedere al DOM per ottenere la forma, e webworkers non ha accesso al DOM, in modo da quei due non funziona assieme. Questo non è esattamente ciò a cui sono destinati i webworker. – adeneo

+0

@adeneo quindi vuoi dire, non c'è modo di farlo funzionare? c'è un altro modo senza usare i dati del form? perché basato su questo articolo per utilizzare il webworker per caricare il file http://kongaraju.blogspot.com/2012/07/large-file-upload-more-than-1gb-using.html sembra buono, ma non lo fa mostra la parte server – Harts

+0

Non sono sicuro, tutto quello che so è che un webworker non può mai avere accesso al DOM, e FormData crea un oggetto praticamente basato su un modulo, e senza accesso al DOM, sarebbe difficile far compilare FormData funziona in quanto non ha affatto accesso al modulo. – adeneo

risposta

12

ho scritto il seguente polyfill per emulare il metodo FormData nei lavoratori web. Poiché i web worker non supportano il DOM, la chiamata del costruttore new FormData(<HTMLFormElement>); non è supportata neanche. Gli oggetti
File e Blob, gli array e le stringhe digitati sono tuttavia supportati dal polyfill.

Originariamente pubblicato come parte della risposta a Upload a File in a Google Chrome Extension. Per vedere un esempio di come può essere utilizzato, dai un'occhiata all'altra risposta.

/* 
* FormData for XMLHttpRequest 2 - Polyfill for Web Worker (c) 2012 Rob W 
* License: Creative Commons BY - http://creativecommons.org/licenses/by/3.0/ 
* - append(name, value[, filename]) 
* - toString: Returns an ArrayBuffer object 
* 
* Specification: http://www.w3.org/TR/XMLHttpRequest/#formdata 
*    http://www.w3.org/TR/XMLHttpRequest/#the-send-method 
* The .append() implementation also accepts Uint8Array and ArrayBuffer objects 
* Web Workers do not natively support FormData: 
*    http://dev.w3.org/html5/workers/#apis-available-to-workers 
**/ 
(function() { 
    // Export variable to the global scope 
    (this == undefined ? self : this)['FormData'] = FormData; 

    var ___send$rw = XMLHttpRequest.prototype.send; 
    XMLHttpRequest.prototype['send'] = function(data) { 
     if (data instanceof FormData) { 
      if (!data.__endedMultipart) data.__append('--' + data.boundary + '--\r\n'); 
      data.__endedMultipart = true; 
      this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + data.boundary); 
      data = new Uint8Array(data.data).buffer; 
     } 
     // Invoke original XHR.send 
     return ___send$rw.call(this, data); 
    }; 

    function FormData() { 
     // Force a Constructor 
     if (!(this instanceof FormData)) return new FormData(); 
     // Generate a random boundary - This must be unique with respect to the form's contents. 
     this.boundary = '------RWWorkerFormDataBoundary' + Math.random().toString(36); 
     var internal_data = this.data = []; 
     /** 
     * Internal method. 
     * @param inp String | ArrayBuffer | Uint8Array Input 
     */ 
     this.__append = function(inp) { 
      var i=0, len; 
      if (typeof inp === 'string') { 
       for (len=inp.length; i<len; i++) 
        internal_data.push(inp.charCodeAt(i) & 0xff); 
      } else if (inp && inp.byteLength) {/*If ArrayBuffer or typed array */ 
       if (!('byteOffset' in inp)) /* If ArrayBuffer, wrap in view */ 
        inp = new Uint8Array(inp); 
       for (len=inp.byteLength; i<len; i++) 
        internal_data.push(inp[i] & 0xff); 
      } 
     }; 
    } 
    /** 
    * @param name  String         Key name 
    * @param value String|Blob|File|Uint8Array|ArrayBuffer Value 
    * @param filename String         Optional File name (when value is not a string). 
    **/ 
    FormData.prototype['append'] = function(name, value, filename) { 
     if (this.__endedMultipart) { 
      // Truncate the closing boundary 
      this.data.length -= this.boundary.length + 6; 
      this.__endedMultipart = false; 
     } 
     var valueType = Object.prototype.toString.call(value), 
      part = '--' + this.boundary + '\r\n' + 
       'Content-Disposition: form-data; name="' + name + '"'; 

     if (/^\[object (?:Blob|File)(?:Constructor)?\]$/.test(valueType)) { 
      return this.append(name, 
          new Uint8Array(new FileReaderSync().readAsArrayBuffer(value)), 
          filename || value.name); 
     } else if (/^\[object (?:Uint8Array|ArrayBuffer)(?:Constructor)?\]$/.test(valueType)) { 
      part += '; filename="'+ (filename || 'blob').replace(/"/g,'%22') +'"\r\n'; 
      part += 'Content-Type: application/octet-stream\r\n\r\n'; 
      this.__append(part); 
      this.__append(value); 
      part = '\r\n'; 
     } else { 
      part += '\r\n\r\n' + value + '\r\n'; 
     } 
     this.__append(part); 
    }; 
})(); 
+0

Perfetto! Ma non dimenticare cambiare tipo di contenuto! – BSQ

Problemi correlati