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,以防万一BlobBuilderBlob 运行良好,但 Blobandroid 原生浏览器 上不起作用,android 原生浏览器使用 BlobBuilder。我预计,BlobBlobBuilder 返回相同的 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 正在建设。如果您指定的值不是 BlobArrayBufferString,在附加到 斑点。

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 本机浏览器上的问题有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

HTML5中的Blob对象的使用

new blob 参数

JS 由前端保存到文件

使用 azure-storage-blob 或 azure-storage 上传和删除 Azure 存储 Blob

如何在 informix 中插入 blob 或 clob 列

如何在 blob 容器中查找热文件或冷文件