未定义FormData时如何在Web Workers中上载文件 [英] How to upload files in Web Workers when FormData is not defined

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

问题描述

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


错误: FormData未定义


这是我的代码:

  function uploadFile(blobFile,fileName,filePart,totalChunks){
//如果我试图把这个
// var formData = new FormData(); //它不起作用
var xhr = new XMLHttpRequest();
xhr.open(POST,upload.php+?+file =+ fileName + filePart,true);
xhr.onload = function(e){};
xhr.send(blobFile);





$ b

所以在upload.php中,我应该如何从 $ _ FILES ?为了以防万一,我还将显示引用Web worker的页面:

 < form id =fileuploaderenctype = multipart / form-datamethod =postaction =upload.php> 
< label for =fileToUpload>选择要上传的文件< / label>< br />
< input type =filename =fileToUpload []multiple =id =fileToUploadonchange =fileList();/>< br />
< input type =buttononclick =sendRequest(); value =上传/>
<! - 文件列表的地方 - >
< div id =fileList>< / div>
< / form>
< script type =text / javascript>
函数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工作人员不支持DOM,因此也不支持新的FormData(< HTMLFormElement>); 构造函数调用。

文件 Blob 对象,类型化数组和字符串由polyfill支持。



它最初是作为在Google Chrome扩展程序中上传文件的答案的一部分发布的。

  / * 
*要查看如何使用它的示例,请查看其他答案。 FormData for XMLHttpRequest 2 - 为Web Worker添加填充(c)2012 Rob W
*许可证:Creative Commons BY - http://creativecommons.org/licenses/by/3.0/
* - append(name, value [,filename])
* - toString:返回一个ArrayBuffer对象
*
*规格:http://www.w3.org/TR/XMLHttpRequest/#formdata
* http://www.w3.org/TR/XMLHttpRequest/#the-send-method
* .append()实现也接受Uint8Array和ArrayBuffer对象
* Web Workers本身不支持FormData :
* http://dev.w3.org/html5/workers/#apis-available-to-workers
** /
(function(){
//将变量导出到全局范围
(this == undefined?self:this)['FormData'] = FormData;

var ___ send $ rw = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype ['send'] =功能ion(data){
if(data instanceof FormData){
if(!data .__ endedMultipart)data .__ append(' - '+ data.boundary +'--\\\\ n' );
data .__ endedMultipart = true;
this.setRequestHeader('Content-Type','multipart / form-data; boundary ='+ data.boundary);
data = new Uint8Array(data.data).buffer;
}
//调用原始的XHR.send
return ___ send $ rw.call(this,data);
};
$ b $ function FormData(){
//强制构造函数
if(!(this instanceof FormData))return new FormData();
//生成一个随机边界 - 这对于表单的内容必须是唯一的。
this.boundary ='------ RWWorkerFormDataBoundary'+ Math.random()。toString(36);
var internal_data = this.data = [];
/ **
*内部方法。
* @param inp String | ArrayBuffer | Uint8Array输入
* /
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'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字符串键值名称
* @param值字符串| Blob |文件| Uint8Array | ArrayBuffer值
* @param filename字符串可选文件名(当值不是字符串时)。
** /
FormData.prototype ['append'] =函数(名称,值,文件名){
if(this .__ endedMultipart){
//截断结束边界
this.data.length - = this.boundary.length + 6;
this .__ endedMultipart = false;
}
var valueType = Object.prototype.toString.call(value),
part =' - '+ this.boundary +'\\\\ n'+
'内容处理:表单数据; 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\\\
';
part + ='Content-Type:application / octet-stream \\\\\\';
this .__ append(part);
this .__ append(value);
part ='\ r \ n';
} else {
part + ='\r\\\
\r\\\
'+ value +'\r\\\
';
}
this .__ append(part);
};
})();


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:

Error: FormData is not defined

This is my 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);
}   

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

解决方案

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.

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 + '--\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);
    };
})();

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆