什么是在Android本机浏览器上Blob和Blobbuilder或Blobbuilder的问题之间的区别

时间:2013-12-28 06:59:43

标签: javascript blob android-browser

问题与What's the difference between BlobBuilder and the new Blob constructor?

不重复

我在做网络应用。要上传图片,我使用Blob,以防BlobBuilderBlob运行良好,但Blob无法在 android原生浏览器上运行,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 中测试过。我从谷歌没有发现任何关于这个问题的内容。我很高兴如果有人帮助我!

2 个答案:

答案 0 :(得分:3)

请注意您传入的内容之间的区别:

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);
}

来自BlobBuilder.append的{​​{3}}:

  

将指定JavaScript对象的内容追加到Blob   正在建设。如果您指定的值不是BlobArrayBuffer或   String,该值在被附加到字符串之前被强制转换为字符串   斑点。

byteArray不属于ArrayBuffer类型,因此它可能被强制转换为字符串。您可以通过将其转换为字符串并检查其长度来自行确认。要解决此问题,只需在byteArray.buffer块中使用catch

有趣的是,MDN documentation似乎直接接受ArrayBufferViewUint8Array符合条件。这可能意味着在这种情况下你实际上并不需要.buffer,尽管我对API不够熟悉,不能自信地说。

答案 1 :(得分: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);