沃梦达 / 编程问答 / php问题 / 正文

未定义 FormData 时如何在 Web Workers 中上传文件

How to upload files in Web Workers when FormData is not defined(未定义 FormData 时如何在 Web Workers 中上传文件)

本文介绍了未定义 FormData 时如何在 Web Workers 中上传文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我通过 Web Worker 上传时,如何在 PHP 中检索 $_FILES?当我尝试使用 FormData 时,出现以下错误:

How can I retrieve $_FILES in PHP when I upload through a Web Worker? When I tried to use FormData, I got the following error:

错误:FormData 未定义

Error: FormData is not defined

这是我的代码:

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

那么在 upload.php 中,我应该如何从 $_FILES 获取 tmp 路径?以防万一,我还将显示引用 Web Worker 的页面:

So in upload.php how am I supposed to get the tmp path from $_FILES ? Just in case, I will also show the page referencing the Web worker:

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

推荐答案

我写了下面的 polyfill 来模拟 Web Workers 中的 FormData 方法.由于 Web Worker 不支持 DOM,因此也不支持 new FormData(); 构造函数调用.
FileBlob 对象、类型化数组和字符串都被 polyfill 支持.

I have written the following polyfill to emulate the FormData method in Web Workers. Since Web workers do not support DOM, the new FormData(<HTMLFormElement>); constructor call is not supported either.
File and Blob objects, typed arrays and strings are supported by the polyfill though.

它最初是作为 在 Google Chrome 扩展程序中上传文件的答案的一部分发布的.要查看如何使用它的示例,请查看其他答案.

It was originally posted as a part of the answer to Upload a File in a Google Chrome Extension. To see an example of how it can be used, have a look at the other answer.

/*
 * 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 + '--
');
            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 + '
' + 
                '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') +'"
';
            part += 'Content-Type: application/octet-stream

';
            this.__append(part);
            this.__append(value);
            part = '
';
        } else {
            part += '

' + value + '
';
        }
        this.__append(part);
    };
})();

这篇关于未定义 FormData 时如何在 Web Workers 中上传文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:未定义 FormData 时如何在 Web Workers 中上传文件