问题与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 中测试过。我从谷歌没有发现任何关于这个问题的内容。我很高兴如果有人帮助我!
答案 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
正在建设。如果您指定的值不是Blob
,ArrayBuffer
或String
,该值在被附加到字符串之前被强制转换为字符串 斑点。
byteArray
不属于ArrayBuffer
类型,因此它可能被强制转换为字符串。您可以通过将其转换为字符串并检查其长度来自行确认。要解决此问题,只需在byteArray.buffer
块中使用catch
。
有趣的是,MDN documentation似乎直接接受ArrayBufferView
,Uint8Array
符合条件。这可能意味着在这种情况下你实际上并不需要.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);