FormData並未在某些瀏覽器上定義,但File也是如此。這裏FORMDATA代碼不使用File對象:
/*
* 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);
};
})();
我的應用程序進行長時間運行(阻塞),使用相當大的斑點(幾百MEG的,通常情況下)的任務,並讓工人來執行 - 這涉及多個XHR步驟 - 它們阻止主線程拋出「等待」屏幕(我可能做錯了)。無論如何,我很高興FormData來到工人。歡呼的回覆! – frumbert
>「在這方面,沒有使用網絡工作者優於主線程的好處。」也許我錯過了一些東西,但由於同步AJAX請求不再支持在主線程中,它們必須在工作線程中使用(我不認爲異步AJAX請求會在工作線程中工作(它們應該在哪裏返回數據if線程更早結束?) - 但也許我錯了)。我看不出如何按特定順序發送和接收請求。 – StanE
@StanE「我認爲異步AJAX請求不會在工作線程中工作」 - 錯誤,異步請求在工作線程中完全正常工作。如果線程被終止,那麼請求可能會被取消(例如,在服務器發送請求回覆之前卸載頁面時發生的情況)。按順序發送請求是一件容易的事,只需等待請求完成(通過事件)即可。 –