So laden Sie Dateien in Web Workers hoch, ohne FormData zu verwenden

Lesezeit: 5 Minuten

Benutzer-Avatar
Hirsche

Wie kann ich abrufen $_FILES in PHP, wenn ich über einen Web Worker hochlade? Als ich versuchte zu benutzen FormDatabekam ich folgenden Fehler:

Fehler: FormData ist nicht definiert

Das ist mein Code:

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

Also in upload.php, wie soll ich den tmp-Pfad bekommen? $_FILES ? Für alle Fälle zeige ich auch die Seite, die auf den Webworker verweist:

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

  • Das formData-Objekt benötigt Zugriff auf das DOM, um das Formular abzurufen, und Webworker haben keinen Zugriff auf das DOM, sodass diese beiden nicht zusammenarbeiten. Das ist nicht wirklich das, wofür Webworker gedacht sind.

    – adeneo

    14. Dezember 2012 um 0:34 Uhr


  • @adeneo, du meinst also, es gibt keine Möglichkeit, das zum Laufen zu bringen? Gibt es eine andere Möglichkeit ohne Formdata? weil basierend auf diesem Artikel Webworker zum Hochladen von Dateien verwendet werden soll kongaraju.blogspot.com/2012/07/… scheint ein guter zu sein, aber er zeigt den Serverteil nicht

    – Hirsche

    14. Dezember 2012 um 0:38 Uhr


  • Ich bin mir nicht sicher, ich weiß nur, dass ein Webworker niemals Zugriff auf das DOM haben kann und FormData ein Objekt ziemlich basierend auf einem Formular erstellt, und ohne Zugriff auf das DOM wäre es schwierig, FormData so zum Laufen zu bringen, wie es funktioniert. überhaupt keinen Zugriff auf das Formular haben.

    – adeneo

    14. Dezember 2012 um 0:46 Uhr


  • @adeneo Das OP versucht nicht, die zu verwenden <form> Objekt (das ist nicht möglich). Stattdessen postet er File Objekte, die aufgrund der richtig empfangen werden strukturierter Klonalgorithmus. Wie ich unten demonstriere, bedeutet das Fehlen von DOM nicht, dass die FormData API kann nicht verwendet werden – siehe Antwort unten.

    – Rob W

    20. Dezember 2012 um 10:36 Uhr

Benutzer-Avatar
Rob W

Ich habe das folgende Polyfill geschrieben, um das zu emulieren FormData Methode in Web Workers. Da Webworker DOM nicht unterstützen, wird die new FormData(<HTMLFormElement>); Konstruktoraufruf wird ebenfalls nicht unterstützt.
File und Blob Objekte, typisierte Arrays und Strings werden jedoch vom Polyfill unterstützt.

Es wurde ursprünglich als Teil der Antwort auf das Hochladen einer Datei in einer Google Chrome-Erweiterung gepostet. Um ein Beispiel zu sehen, wie es verwendet werden kann, werfen Sie einen Blick auf die andere Antwort.

/*
 * 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);
    };
})();

  • Perfekt ! Aber vergessen Sie nicht, den Inhaltstyp zu ändern!

    – BSQ

    21. Mai 2014 um 16:29 Uhr

1011810cookie-checkSo laden Sie Dateien in Web Workers hoch, ohne FormData zu verwenden

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy