Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

XHR, HTML5: Add workaround for Gecko 2/5/6 and Android browsers, that…

… are unable to properly send blobs in FormData.
  • Loading branch information...
commit 7ce1500a94ae8555d139b674a34942b707518deb 1 parent c4fbdf3
@jayarjo jayarjo authored
View
105 bin/js/moxie.js
@@ -1840,7 +1840,10 @@ define('moxie/file/Blob', [
this.ruid = null;
}
- blobpool[this.uid] = data || '';
+ data = data || '';
+ this.size = data.length;
+
+ blobpool[this.uid] = data;
},
/**
@@ -2807,6 +2810,16 @@ define("moxie/xhr/FormData", [
},
/**
+ Retrieves blob field name.
+
+ @method geBlobName
+ @return {String} Either Blob field name or null
+ */
+ getBlobName: function() {
+ return _blobField || null;
+ },
+
+ /**
Loop over the fields in FormData and invoke the callback for each of them.
@method each
@@ -2847,6 +2860,11 @@ define("moxie/core/utils/Env", [
], function(Basic) {
var browser = [{
+ s1: navigator.userAgent,
+ s2: "Android",
+ id: "Android Browser", // default or Dolphin
+ sv: "Version"
+ },{
s1: navigator.userAgent, // string
s2: "Chrome", // substring
id: "Chrome" // identity
@@ -2905,6 +2923,10 @@ define("moxie/core/utils/Env", [
s2: "iPad",
id: "iOS"
},{
+ s1: navigator.userAgent,
+ s2: "Android",
+ id: "Android"
+ },{
s1: navigator.platform,
s2: "Linux",
id: "Linux"
@@ -5795,7 +5817,7 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
], function(extensions, Basic, File, Blob, FormData, x, Env, parseJSON) {
function XMLHttpRequest() {
- var _xhr2, filename;
+ var self = this, _xhr2, filename;
Basic.extend(this, {
send: function(meta, data) {
@@ -5804,6 +5826,34 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
, fd
;
+ // Gecko 2/5/6 can't send blob in FormData: https://bugzilla.mozilla.org/show_bug.cgi?id=649150
+ // Android browsers (default one and Dolphin) seem to have the same issue, see: #613
+ var blob, fr
+ , isGecko2_5_6 = (Env.browser === 'Mozilla' && window.FormData && window.FileReader && !window.FileReader.prototype.readAsArrayBuffer)
+ , isAndroidBrowser = Env.browser === 'Android Browser'
+ ;
+ // here we go... ugly fix for ugly bug
+ if ((isGecko2_5_6 || isAndroidBrowser) && data instanceof FormData && data.hasBlob() && !data.getBlob().isDetached()) {
+ // get original blob
+ blob = data.getBlob().getSource();
+ // only Blobs have problem, Files seem ok
+ if (blob instanceof window.Blob && window.FileReader) {
+ // preload blob in memory to be sent as binary string
+ fr = new window.FileReader();
+ fr.onload = function() {
+ // overwrite original blob
+ data.append(data.getBlobName(), new Blob(null, {
+ type: blob.type,
+ data: fr.result
+ }));
+ // invoke send operation again
+ self.send.call(target, meta, data);
+ };
+ fr.readAsBinaryString(blob);
+ return; // do not proceed further
+ }
+ }
+
_xhr2 = new window.XMLHttpRequest();
// extract file name
@@ -5818,31 +5868,7 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
});
}
- // prepare data to be sent and convert if required
- if (data instanceof Blob) {
- if (data.isDetached()) {
- mustSendAsBinary = true;
- }
- data = data.getSource();
- } else if (data instanceof FormData) {
- if (data.hasBlob() && data.getBlob().isDetached()) {
- // ... and here too
- data = _prepareMultipart.call(target, data);
- mustSendAsBinary = true;
- } else {
- fd = new window.FormData();
-
- data.each(function(value, name) {
- if (value instanceof Blob) {
- fd.append(name, value.getSource());
- } else {
- fd.append(name, value);
- }
- });
- data = fd;
- }
- }
-
+ // request response type
if ("" !== meta.responseType) {
if ('json' === meta.responseType && !Env.can('receive_response_type', 'json')) { // we can fake this one
_xhr2.responseType = 'text';
@@ -5891,6 +5917,31 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
}());
+ // prepare data to be sent and convert if required
+ if (data instanceof Blob) {
+ if (data.isDetached()) {
+ mustSendAsBinary = true;
+ }
+ data = data.getSource();
+ } else if (data instanceof FormData) {
+ if (data.hasBlob() && data.getBlob().isDetached()) {
+ // ... and here too
+ data = _prepareMultipart.call(target, data);
+ mustSendAsBinary = true;
+ } else {
+ fd = new window.FormData();
+
+ data.each(function(value, name) {
+ if (value instanceof Blob) {
+ fd.append(name, value.getSource());
+ } else {
+ fd.append(name, value);
+ }
+ });
+ data = fd;
+ }
+ }
+
// send ...
if (!mustSendAsBinary) {
_xhr2.send(data);
View
6 bin/js/moxie.min.js
3 additions, 3 deletions not shown
View
81 src/javascript/runtime/html5/xhr/XMLHttpRequest.js
@@ -27,7 +27,7 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
], function(extensions, Basic, File, Blob, FormData, x, Env, parseJSON) {
function XMLHttpRequest() {
- var _xhr2, filename;
+ var self = this, _xhr2, filename;
Basic.extend(this, {
send: function(meta, data) {
@@ -36,6 +36,34 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
, fd
;
+ // Gecko 2/5/6 can't send blob in FormData: https://bugzilla.mozilla.org/show_bug.cgi?id=649150
+ // Android browsers (default one and Dolphin) seem to have the same issue, see: #613
+ var blob, fr
+ , isGecko2_5_6 = (Env.browser === 'Mozilla' && window.FormData && window.FileReader && !window.FileReader.prototype.readAsArrayBuffer)
+ , isAndroidBrowser = Env.browser === 'Android Browser'
+ ;
+ // here we go... ugly fix for ugly bug
+ if ((isGecko2_5_6 || isAndroidBrowser) && data instanceof FormData && data.hasBlob() && !data.getBlob().isDetached()) {
+ // get original blob
+ blob = data.getBlob().getSource();
+ // only Blobs have problem, Files seem ok
+ if (blob instanceof window.Blob && window.FileReader) {
+ // preload blob in memory to be sent as binary string
+ fr = new window.FileReader();
+ fr.onload = function() {
+ // overwrite original blob
+ data.append(data.getBlobName(), new Blob(null, {
+ type: blob.type,
+ data: fr.result
+ }));
+ // invoke send operation again
+ self.send.call(target, meta, data);
+ };
+ fr.readAsBinaryString(blob);
+ return; // do not proceed further
+ }
+ }
+
_xhr2 = new window.XMLHttpRequest();
// extract file name
@@ -50,31 +78,7 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
});
}
- // prepare data to be sent and convert if required
- if (data instanceof Blob) {
- if (data.isDetached()) {
- mustSendAsBinary = true;
- }
- data = data.getSource();
- } else if (data instanceof FormData) {
- if (data.hasBlob() && data.getBlob().isDetached()) {
- // ... and here too
- data = _prepareMultipart.call(target, data);
- mustSendAsBinary = true;
- } else {
- fd = new window.FormData();
-
- data.each(function(value, name) {
- if (value instanceof Blob) {
- fd.append(name, value.getSource());
- } else {
- fd.append(name, value);
- }
- });
- data = fd;
- }
- }
-
+ // request response type
if ("" !== meta.responseType) {
if ('json' === meta.responseType && !Env.can('receive_response_type', 'json')) { // we can fake this one
_xhr2.responseType = 'text';
@@ -123,6 +127,31 @@ define("moxie/runtime/html5/xhr/XMLHttpRequest", [
}());
+ // prepare data to be sent and convert if required
+ if (data instanceof Blob) {
+ if (data.isDetached()) {
+ mustSendAsBinary = true;
+ }
+ data = data.getSource();
+ } else if (data instanceof FormData) {
+ if (data.hasBlob() && data.getBlob().isDetached()) {
+ // ... and here too
+ data = _prepareMultipart.call(target, data);
+ mustSendAsBinary = true;
+ } else {
+ fd = new window.FormData();
+
+ data.each(function(value, name) {
+ if (value instanceof Blob) {
+ fd.append(name, value.getSource());
+ } else {
+ fd.append(name, value);
+ }
+ });
+ data = fd;
+ }
+ }
+
// send ...
if (!mustSendAsBinary) {
_xhr2.send(data);
Please sign in to comment.
Something went wrong with that request. Please try again.