数据协议URL大小限制

93

"data:" URL 方案的值是否有大小限制?我对流行的Web浏览器中的限制感兴趣。换句话说,在<img src="data:image/jpg;base64,base64_encoded_data" />background-image: url(data:image/jpg;base64,base64_encoded_data)中,data:image/jpg;base64,base64_encoded_data可以有多长?

11个回答

135
简答:数据URI的限制因应用程序而异。
有很多答案。由于该问题在5年前被提出,大多数答案现在已经过时了,但是这个问题在谷歌搜索结果中排名第一,因为数据URI现在得到广泛支持,IE 7/8不再是一个相关的浏览器。下面有很多参考资料,因为今天的答案比较微妙。
数据URI限制
数据URI规范没有定义大小限制,但说应用程序可以自行设定限制。
谷歌浏览器-对于当前文档为2MB。否则,限制为任意 blob 的内存存储限制:如果是x64且不是ChromeOS或Android,则为2GB;否则,是total_physical_memory / 5(source)。
火狐浏览器-无限制 IE≥9和Edge-4GB Safari和移动版Safari-?
一种技术,其上限更高(Chrome中为500MiB),可能是您使用情况的替代方案,即通过URL.createObjectURL()使用URL APIFile API中的blob来生成Blob URL。关于这方面的示例,请参见{{link5:使用URL.createObjectURL()}}。
如何编写文件/将其提供给用户中提到的其他一些替代方案包括:FileSaver.js, StreamSaver.jsJSZip
您可以使用Modernizr检测是否支持超过32kb的数据URI
相关问题

1
Chrome的限制超过了2MB,尽管我不知道确切的限制是多少。它似乎对HTML文档中嵌入的图像比输入到地址栏的数据URI更有效,后者在3MB时几乎使Chrome停滞不前,但两者都可以使用。 - George Helyar
1
@GeorgeHelyar 感谢您添加这个。您能否提供嵌入式情况下更高数字的参考资料? - Taylor D. Edmiston
1
@GeorgeHelyar 如果你能在 js fiddle 等平台上提供实证证据,我很乐意添加它。 - Taylor D. Edmiston
@GeorgeHelyar 如果数据URI是渐进式JPEG,则您的测试可能无效,因为它仍将使用部分数据呈现。只是一个想法。 - user66649
1
Chrome的限制仅适用于您所在文档的URL。如果您的设备具有足够的内存,您可以轻松地将几GB的视频作为dataURI加载。而且,在2017年将createObjectURL称为“实验性技术”是... - Kaiido
显示剩余4条评论

44

我刚刚进行了简要检查,嵌入了八个不同尺寸的Jpeg图像,大小从3,844到2,233,076字节不等。

在我的Windows 7(64位)系统上,以下所有浏览器都正确显示了每个图像:

  • Chromium 14.0.816.0
  • Firefox 11.0
  • Google Chrome 18.0.1025.142
  • Internet Explorer 9.0.5 (64 Bit)
  • Opera 11.62
  • Safari 5.1.5

3
我的IE9在此期间变成了IE10,所以我只能保证它在IE9中可以正常工作。而且它在IE10中仍然可以运行。这里有一张测试图片,大小约为244KBytes(请查看源代码):http://www.butterweck.de/test/dataimgtest.html - miasbeck
11
@miasbeck,为什么止步于2MB? - Pacerier
@Pacerier 没有特定的原因。我只是认为我的图像可能会达到最大尺寸。 - miasbeck
实际上,我的IE(11.*)也无法显示该图片。 - Alexis Paques
还有一个相对晦涩的数据点。如果您使用数据URI将图像数据传递到Chromecast(例如专辑封面),则支持的最大长度为64,000字节(而不是64KB)。 - aroth

18

来自http://www.ietf.org/rfc/rfc2397.txt

"data:" URL 方案仅适用于短值。请注意,某些使用URL的应用程序可能会施加长度限制;例如,在HTML中嵌入在<A>锚中的URL具有由HTML的SGML声明确定的长度限制[RFC1866]。LITLEN(1024)限制了单个属性值文字中可以出现的字符数,ATTSPLEN(2100)限制了在标记中出现的所有属性值规范的所有长度的总和,TAGLEN(2100)限制了标记的整体长度。


1
看起来在传统的HTML中“数据”毫无用处。然而,XHTML和CSS可能有不同的限制。 - LicenseQ
你需要找到XHTML的模式和CSS的规范并加以了解。 - John Saunders
2
阅读规范是有趣的,但我认为试图遵循它并不明智。作为Web开发人员,我们天生就处于技术的前沿。如果你一味地遵循规范,那么你会不必要地束缚自己。LicenseQ完全正确,这些限制使数据URL变得完全无用。但它们并不是无用的,这些限制也并非真正的限制(因为所有浏览器供应商都选择忽略它们)。所以,让自己自由吧!利用miasbeck的信息来获得优势。这是我们程序实际运行的实际现实。 - Stijn de Witt
@StijndeWitt,确切地说,如果对于一个网络问题的“答案”没有涉及到任何浏览器的行为,那么这根本不是一个答案。 - Pacerier


7

2017的答案是:使用函数dataURLtoBlob将数据转换为blob。

function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}

然后创建 Blob URL

var temp_url = window.URL.createObjectURL(blob);

如果您需要,在新窗口中使用它。

var redirectWindow = window.open('');
redirectWindow.document.write('<iframe src="' + temp_url + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen></iframe>')      

2017年,Chrome/Firefox可处理大文件。


1
window.open(temp_url, '_blank'); 看起来不需要使用 iframe 等。需要注意的一点是,Chrome 不允许在 blob URL 上执行“文件 > 另存为”操作。 - Joel
由于 charCodeAt 无法正确转换所有字符,我建议使用 new TextEncoder('utf-8').encode。我在我的帖子中给出了一个例子。 - select
我使用 charCodeAt 没有遇到任何问题。我使用了 waza123 的解决方案,它非常好用。 - ashilon
只是确认一下,当使用 blob 时,我们可以避免在前端向后端发送文件时的文件大小限制(base64)吗? - Shulz

5

这真的是"数据URI方案"。

根据维基百科页面,IE7不支持,而IE8测试版将其限制为32kB的数据。


3
关于Web浏览器的限制,MSIE 6/7不支持data url方案... 更多信息请参见维基百科 每个浏览器的长度限制不同 - 我相信IE8允许最多32KB,而Opera是4KB,但无法确定其他浏览器...

3

提醒:我能够通过JavaScript ajax调用以data url的形式在Firefox 3.5中加载一个130K的图像。但是,在IE 8中,该图像被截断了,而在FF中则完整显示。


2

看起来在Firefox 3.6中限制是600KB。


1
有任何支持这个观点的链接吗? - xdhmoore
这里有一个链接,展示了Firefox的限制:https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs(查找限制)。 - Carlitos Way
@CarlitosWay 找不到它。 - FluorescentGreen5
@FluorescentGreen5 那是2年前的事了,我相信Firefox的规格已经改变了... - Carlitos Way
2
@CarlitosWay 啊,我刚刚查了一下规格,它现在说是无限的。 - FluorescentGreen5

1

我尝试了waza123的代码,但是charCodeAt方法不能正确转换所有字符。这里是我为在浏览器中创建大型下载的解决方案。(我用它来处理JSON数据)

function exportToFile(jsonData, fileName) {
    const u8arr = new TextEncoder('utf-8').encode(JSON.stringify(jsonData, null, 2));
    const url = window.URL.createObjectURL(new Blob([u8arr], { type: 'application/json' }));
    const element = document.createElement('a');
    element.setAttribute('href', url);
    element.setAttribute('download', fileName);
    element.style.display = 'none';
    document.body.appendChild(element);
    element.click();
    document.body.removeChild(element);
}

1
这对我有用。我只需要为我的Angular应用程序安装TextEncoder typings:npm install --save @types/text-encoding - jokab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接