The state of binary data in the browser
The state of binary data in the browser
Or: "So you wanna store a Blob, huh?"
TL;DR
Don't try to store Blobs directly in IndexedDB, unless you want to cry. Browsers still suck at it.
PouchDB and blob-util have workarounds to avoid the browser bugs.
Long version
I know it's 2015, and Blobs/IndexedDB should be universally supported already. But sadly they're not, so here's the sorry state of things.
Browsers have three ways of storing data: LocalStorage, WebSQL, and IndexedDB. They all suck for different reasons, which is why there are so many abstraction layers out there: PouchDB, LocalForage, Lawnchair, YDN-DB, MakeDrive, etc.
Browsers don't consistently handle Blobs either. The caniuse.com page for Blobs is a bit disingenuous; really IE and Firefox should be yellowy-green, because they don't consistently support all the canvas
and FileReader
methods. Blobs in Chrome also have severe bugs before v43.
So let's see all the different browsers and storage engines, and how they stack up:
LocalStorage
Supported by most browsers, althought not Chrome extensions, Chrome apps, web workers, or service workers.
You can store Blobs in LocalStorage as base64 strings, which is really inefficient. Plus, many LocalStorage implementations only let you store up to 5MB, so you hit the limit pretty fast.
WebSQL and IndexedDB have much higher limits. So let's see how the different browsers work with those two.
Chrome
Supports both IndexedDB and WebSQL. Chrome originally got IndexedDB in v23.
WebSQL doesn't support storing Blobs themselves, only strings. You can store binary strings directly, which is the most efficient, but then the '\u0000'
byte causes data to get lost. PouchDB works around this by eliminating the '\u0000'
in a safe and very efficient way.
IndexedDB has many Blob bugs in Chrome. Here's the history:
- pre-v36: Chrome didn't support IndexedDB Blobs at all, so PouchDB (and most other libs like LocalForage) work around this by storing data as base64-encoded strings. Note this also includes Android up to Lollipop 5.0. (Chromium issue)
- v37: Chrome introduced broken support for Blobs (issue). It was broken because the mimetype wasn't correctly returned.
- v38: The mimetype bug was fixed in v38, but Chrome had two more Blob/IndexedDB bugs: this one and this one. The second one in particular was a race condition causing data to be permanently unreadable, which was a big enough blocker that PouchDB continued downgrading Chrome to base64-only.
- v43: Chrome finally fixed all the Blob bugs, so PouchDB auto-detects it and upgrades to Blob support (test it out here).
Android
Android didn't support IndexedDB until 4.4 Kitkat, and as of this writing, more than half of all Android devices are still pre-Kitkat. Some Samsung/HTC Android 4.3 devices have a broken implementation of IndexedDB based on an older version of the spec. PouchDB detects this and falls back to WebSQL.
Additionally, many pre-4.4 devices don't support Blobs correctly - either they're using vendor prefixes likewindow.webkitURL
or they use the deprecated BlobBuilder
API. blob-util works around these issues.
4.4 Kitkat devices will either have Chrome 30 or Chrome 33, depending on whether it's 4.4.0-4.4.1 or 4.4.2+. Lollipop is auto-updating; it debuted with Chrome v37 and is up to v42 as of this writing.
Note this applies to WebViews (i.e. Cordova/PhoneGap apps), the stock browser, and most of the non-Chrome/non-Firefox browsers you'll find in the Play Store, since they just wrap a WebView (e.g. CM Browser, Dolphin Browser, and Link Bubble).
Safari/iOS
WebSQL: Safari WebSQL has the same '\u0000' bug as Chrome (on both iOS and desktop), as well as another bug that affects Safari pre-v7.1 and iOS pre-8.0 where all data is coerced to UTF-16 instead of UTF-8, meaning it takes up twice the space. PouchDB detects UTF-16 vs UTF-8 encoding and reacts accordingly.
IndexedDB: The less said about Safari IndexedDB, the better. It is so buggy that PouchDB, LocalForage, and YDN-DB all ignore it. For what it's worth, though, it doesn't support binary Blobs according to HTML5Test.com.
IE/Firefox
Neither one supports WebSQL, but they're actually both great about storing Blobs in IndexedDB. IE has supported Blobs since it introduced IndexedDB in v10, and Firefox has had them since 2011.
That being said, these two have bugs related to the Blob/FileReader APIs themselves:
IE doesn't have FileReader.prototype.readAsBinaryString
(only readAsArrayBuffer
), so if you want to convert a Blob to a binary string or a base64 string most efficiently, you want to use readAsBinaryString
everywhere but IE. PouchDB and blob-util both do this.
Firefox, conversely, doesn't have the canvas.toBlob()
method, so if you want to convert a canvas
to a Blob, you need to use canvas.toDataURL()
and convert the dataURL to a Blob instead. blob-util does this under the hood.
More resources
A lot of this is documented in the PouchDB FAQs, the PouchDB 3.0.6 release notes, and "10 things I learned from reading and writing the PouchDB source". More research on browser storage can be found in this gist.
I'm not aware of any database library that stores Blobs as efficiently or in as many browsers as PouchDB (if I'm wrong, though, then let me know on Twitter ). You can even use the localstorage adapter to store Blobs that way (in which case they will be inefficiently base64-encoded). And the proof is in the pudding: the PouchDB test suite is insane.
The state of binary data in the browser的更多相关文章
- JAXB - XML Schema Types, Binary Data
Data that has no "natural" representation with printable characters must, for inclusion in ...
- String or binary data would be truncated. The statement has been terminated.
常见的情况为:插入的值大于字段定义的最大长度. String or binary data would be truncated. The statement has been terminated
- String or binary data would be truncated
在使用Typed Dataset进行数据的插入时,会报这样的错:String or binary data would be truncated. 我碰到的原因是 数据库中字段的长度过段,插入时内容被 ...
- Server Job: error: String or binary data would be truncated. The statement has been terminated.
"String or binary data would be truncated. The statement has been terminated" most probabl ...
- Bubble Babble Binary Data Encoding的简介以及bubblepy的安装使用方法
Bubble Babble Binary Data Encoding是由Antti Huima创建的一种编码方法,可以把二进制信息表示为由交替的元音和辅音组成的伪词(pseudo-words),主要用 ...
- 20180820 SQL 提示Error: String or binary data would be truncated
Error: String or binary data would be truncated,错误,是因为栏位给出的长度不够,增加初始化长度就可以了. 除了创建表的增加长度情况,还有一种是,SELE ...
- Uploading File using Ajax and receiving binary data in Asp.net (C#)[转]
基础知识,可由此衍生.原文:http://uniapple.net/blog/?p=2050 In this post, I will show you how to upload a file us ...
- Interpret bytes as packed binary data
7.1. struct — Interpret bytes as packed binary data — Python 3.6.5 documentation https://docs.python ...
- IDA解析so文件异常(Binary data is incorrect maximum possible value is xx)
错误信息 Binary data is incorrect maximum possible value is 0 错误原因 so文件损坏 或者ida换成32 解决办法 重新获得so文件,或者调整id ...
随机推荐
- ViewPager的用法实例
前言:最近在做一个项目,文件管理器,能够在主界面通过滑动选择:手机,内存卡,云端的不同界面,因此就用到了ViewPager. 起步阶段,ViewPager写好了,对应的Adapter也写好了,测试通过 ...
- 网络学习笔记----01--pathping跟踪数据包路径
操作系统win7 Pathping主要用于提供有关在来源和目标之间的中间跃点处的网络滞后和网络丢失的信息. Pathping将多个回显请求消息发送到来源和目标之间的各个路由器一段时间,然后根据各个路由 ...
- 程序员带你十天快速入门Python,玩转电脑软件开发(一)
关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...
- VS2010无法打开CSS问题
安装了VS2010的SP1补丁后,发现打开css文件时出现下面问题: 一点击css文件就弹出:未能完成操作.未指定的错误.无法正常进入. [解决方法]安装最新Web Standards Update补 ...
- Delphi 类方法和普通方法的区别 .
//类声明 TMyClass = class public class procedure MyProc; //类方式 constructor Create; //Crea ...
- CorAnimation7-高效绘图、图像IO以及图层性能
高效绘图 软件绘图 术语绘图通常在Core Animation的上下文中指代软件绘图(意即:不由GPU协助的绘图).在iOS中,软件绘图通常是由Core Graphics框架完成来完成.但是,在一些必 ...
- why slow thinking wins
今天Hacker News上的一篇文章<为什么想得慢的人能赢>引起了广泛的讨论. 网友Scott Burson在文章后评论说:"之前,我雇佣了一位TopCoder冠军,原本预计他 ...
- WPF 窗体中的 Canvas 限定范围拖动 鼠标滚轴改变大小
xaml代码: <Canvas Name="movBg"> <Canvas.Background> <LinearGradientBrush EndP ...
- 使用for循环嵌套实现乘法口诀表
九九乘法表的实现: package com.liaojianya.chapter1; /** * This program demonstrates the way of using * for-lo ...
- 一个由IsPrime算法引发的细节问题
//******************************* // // 2014年9月18日星期四,于宿舍撰写 // 作者:夏华林 // //******************* ...