Blob 和 Blobbuilder 或 Blobbuilder 在 android 本机浏览器上的问题有啥区别
Posted
技术标签:
【中文标题】Blob 和 Blobbuilder 或 Blobbuilder 在 android 本机浏览器上的问题有啥区别【英文标题】:what's the difference between Blob and Blobbuilder or Blobbuilder's issue on android native browserBlob 和 Blobbuilder 或 Blobbuilder 在 android 本机浏览器上的问题有什么区别 【发布时间】:2014-01-15 17:02:58 【问题描述】:问题与What's the difference between BlobBuilder and the new Blob constructor?不重复
我正在做网络应用程序。上传图片我使用Blob
,以防万一BlobBuilder
。 Blob
运行良好,但 Blob
在 android 原生浏览器 上不起作用,android 原生浏览器使用 BlobBuilder
。我预计,Blob
和 BlobBuilder
返回相同的 blob,但他们没有。这是我的代码:
base64toBlob: function(b64Data, contentType, sliceSize)
var BlobBuilder, blob, byteArray, byteCharacters, byteNumbers, charCodeFromCharacter, err, posIndex;
if (contentType == null)
contentType = '';
if (sliceSize == null)
sliceSize = 1024;
posIndex = b64Data.indexOf('base64,');
if (posIndex !== -1)
b64Data = b64Data.substring(posIndex + 7);
charCodeFromCharacter = function(c)
return c.charCodeAt(0);
;
byteCharacters = atob(b64Data.replace(/\s/g, ''));
byteNumbers = Array.prototype.map.call(byteCharacters, charCodeFromCharacter);
byteArray = new Uint8Array(byteNumbers);
try
blob = new Blob([byteArray.buffer],
type: contentType
);
return blob;
catch (_error)
err = _error;
BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
blob = new BlobBuilder();
blob.append(byteArray.buffer);
return blob.getBlob(contentType);
我在发送请求时记录了日志
blobImg = base64toBlob(base64Data, imageType);
alert(JSON.stringify(blobImg));
// alert shows "type": "image/jpeg", "size": 10251 when blob worked
// alert shows "type": "image/jpeg", "size": 27822 when blobbuilder worked
ajaxRequest.send(blobImg);
我尝试在所有浏览器上上传同一张图片。在 Chrome 和其他浏览器上,我从日志 "type": "image/jpeg", "size": 10251
获取并请求发送成功,但在 android 本机浏览器上,我得到 "type": "image/jpeg", "size": 27822
并且请求失败,状态码为 0
。在 android 浏览器上工作 catch
部分(我猜,这意味着 Android 原生浏览器不支持 Blob)我在 android 4.1.2 中测试过。我从谷歌没有发现任何关于这个问题的信息。如果有人帮助我,我会很高兴!
【问题讨论】:
我有同样的问题。你知道如何解决这个问题吗?也可以接受一种解决方法。高级赞赏。 @ablian,我创建了一个答案 【参考方案1】:注意你传入的内容的区别:
try
blob = new Blob([byteArray.buffer], // use of .buffer
type: contentType
);
return blob;
catch (_error)
err = _error;
BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
blob = new BlobBuilder();
blob.append(byteArray); // just uses the raw array
return blob.getBlob(contentType);
从MDN documentation 到BlobBuilder.append
:
将指定 javascript 对象的内容附加到
Blob
正在建设。如果您指定的值不是Blob
、ArrayBuffer
或String
,在附加到 斑点。
byteArray
不是ArrayBuffer
类型,因此它可能被强制转换为字符串。您可以通过将其转换为字符串并检查其长度来自己确认这一点。要修复它,只需在 catch
块中使用 byteArray.buffer
。
有趣的是,Blob
constructor 似乎直接接受了 ArrayBufferView
,而您的 Uint8Array
则符合此条件。这可能意味着在这种情况下您实际上并不需要 .buffer
,尽管我对 API 不够熟悉,因此无法自信地说。
【讨论】:
好吧,这使我的整个答案无效。提问时请注意并永远不要改写代码。为这样一个不太常见的问题提供答案可能需要大量的时间投入,而且浪费这种努力是非常令人沮丧的,因为问题中的代码实际上并不是出现错误的代码。始终直接从源代码复制代码并尽可能运行摘录。【参考方案2】:它适用于我们的情况,我不知道,它是否适合您。
base64toBlob: (b64Data, contentType = '', needArrBuffer) ->
posIndex = b64Data.indexOf 'base64,'
if posIndex isnt -1
b64Data = b64Data.substring posIndex + 7
charCodeFromCharacter = ( c ) ->
c.charCodeAt( 0 )
byteCharacters = b64Data
b64Data = b64Data.replace(/\s/g, '')
try
byteCharacters = atob?(b64Data)
byteCharacters ?= Base64.decode(b64Data)
catch err
byteNumbers = Array.prototype.map.call(byteCharacters,
charCodeFromCharacter)
byteArray = new Uint8Array(byteNumbers)
try
new Blob [byteArray.buffer], type: contentType
catch err
if needArrBuffer
# Android browser cannot send Blob by XHR, so we use ArrayBuffer instead of Blob
return byteArray.buffer
Util.log 'Warning: No native Blob supported! ' + err.message
BlobBuilder = window.WebKitBlobBuilder || window.MozBlobBuilder
blob = new BlobBuilder()
blob.append(byteArray.buffer)
blob.getBlob(contentType)
blobImg = base64toBlob(base64Data, imageType, true);
ajaxRequest.send(blobImg);
【讨论】:
以上是关于Blob 和 Blobbuilder 或 Blobbuilder 在 android 本机浏览器上的问题有啥区别的主要内容,如果未能解决你的问题,请参考以下文章
使用 azure-storage-blob 或 azure-storage 上传和删除 Azure 存储 Blob