在Android Native浏览器中上传空文件

我正在创build一个手机网站,调整照片大小并上传。

$('#ImgPreview canvas').each(function(pIndex) { vFormData.append(pIndex, canvasToJpegBlob($(this)[0]), vIssueId +'-attachment0'+ pIndex +'.jpg'); }); $.ajax({ url: '/api/ob/issuefileupload', data: vFormData, processData: false, contentType: false, type: 'POST' }).done(function(pData) { window.location = '/issue?id='+ vIssueId; }).fail(function(pJqXHR) { alert(My.Strings.UploadFailed); }); 

这适用于Android版Chrome和iOS版Safari,但在本机Android浏览器中,文件的内容长度为0,名称为Blob + UID。 当文件被添加到formdata的大小也似乎相当大(900K对抗到50K在Chrome中)。

canvasToJpegBlob函数:

 function canvasToJpegBlob(pCanvas) { var vMimeType = "image/jpeg", vDataURI, vByteString, vBlob, vArrayBuffer, vUint8Array, i, vBlobBuilder; vDataURI = pCanvas.toDataURL(vMimeType, 0.8); vByteString = atob(vDataURI.split(',')[1]); vArrayBuffer = new ArrayBuffer(vByteString.length); vUint8Array = new Uint8Array(vArrayBuffer); for (i = 0; i < vByteString.length; i++) { vUint8Array[i] = vByteString.charCodeAt(i); } try { vBlob = new Blob([vUint8Array.buffer], {type : vMimeType}); } catch(e) { window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if (e.name === 'TypeError' && window.BlobBuilder) { vBlobBuilder = new BlobBuilder(); vBlobBuilder.append(vUint8Array.buffer); vBlob = vBlobBuilder.getBlob(vMimeType); } else if (e.name === 'InvalidStateError') { vBlob = new Blob([vUint8Array.buffer], {type : vMimeType}); } else { alert(My.Strings.UnsupportedFile); } } return vBlob; } 

有没有什么办法让原生Android浏览器工作?

Solutions Collecting From Web of "在Android Native浏览器中上传空文件"

我也遇到了这个问题,需要提出一个更通用的解决scheme,因为在某些情况下,我将无法控制服务器端代码。

最终我达到了几乎完全透明的解决scheme。 这种方法是用一个blob来填充破损的FormData ,以multipart/form-data的必要格式附加multipart/form-data 。 它用一个读取blob的版本覆盖XHR的send() ,将其发送到请求中发送的缓冲区中。

这里是主要的代码:

 var // Android native browser uploads blobs as 0 bytes, so we need a test for that needsFormDataShim = (function () { var bCheck = ~navigator.userAgent.indexOf('Android') && ~navigator.vendor.indexOf('Google') && !~navigator.userAgent.indexOf('Chrome'); return bCheck && navigator.userAgent.match(/AppleWebKit\/(\d+)/).pop() <= 534; })(), // Test for constructing of blobs using new Blob() blobConstruct = !!(function () { try { return new Blob(); } catch (e) {} })(), // Fallback to BlobBuilder (deprecated) XBlob = blobConstruct ? window.Blob : function (parts, opts) { var bb = new (window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder); parts.forEach(function (p) { bb.append(p); }); return bb.getBlob(opts ? opts.type : undefined); }; function FormDataShim () { var // Store a reference to this o = this, // Data to be sent parts = [], // Boundary parameter for separating the multipart values boundary = Array(21).join('-') + (+new Date() * (1e16*Math.random())).toString(36), // Store the current XHR send method so we can safely override it oldSend = XMLHttpRequest.prototype.send; this.append = function (name, value, filename) { parts.push('--' + boundary + '\nContent-Disposition: form-data; name="' + name + '"'); if (value instanceof Blob) { parts.push('; filename="'+ (filename || 'blob') +'"\nContent-Type: ' + value.type + '\n\n'); parts.push(value); } else { parts.push('\n\n' + value); } parts.push('\n'); }; // Override XHR send() XMLHttpRequest.prototype.send = function (val) { var fr, data, oXHR = this; if (val === o) { // Append the final boundary string parts.push('--' + boundary + '--'); // Create the blob data = new XBlob(parts); // Set up and read the blob into an array to be sent fr = new FileReader(); fr.onload = function () { oldSend.call(oXHR, fr.result); }; fr.onerror = function (err) { throw err; }; fr.readAsArrayBuffer(data); // Set the multipart content type and boudary this.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary); XMLHttpRequest.prototype.send = oldSend; } else { oldSend.call(this, val); } }; } 

只要像这样使用它,之后调用fd.append(name, value)

 var fd = needsFormDataShim ? new FormDataShim() : new FormData(); 

如何试图在canvas上绘制,使用matrix将其缩放到所需的大小,然后使用canvas.toDataURL将其发送到服务器。 看看这个问题 。

我用这个来解决这个问题:

 // not use blob, simply use key value var form = new FormData(); // get you content type and raw data from data url form.append( 'content_type', type); form.append( 'content', raw);