为了账号安全,请及时绑定邮箱和手机立即绑定

是否应立即将图像src设置为数据URL?

是否应立即将图像src设置为数据URL?

撒科打诨 2019-07-26 15:22:52
是否应立即将图像src设置为数据URL?考虑以下(脆弱的)JavaScript代码:var img = new Image;img.src = "data:image/png;base64,..."; // Assume valid data// Danger(?) Attempting to use image immediately after setting srcconsole.log( img.width, img.height );someCanvasContext.drawImage( img, 0, 0 );// Danger(?) Setting onload after setting srcimg.onload = function(){ console.log('I ran!'); };问题图像宽度和高度应该立即正确吗?画布应该立即开始工作吗?是否应该onload调用回调(在src更改后设置)?实验测试我创建了一个具有类似代码的简单测试页面。在Safari我的第一次测试,都是由本地打开HTML网页(file:///URL),并从我的服务器加载它,结果显示一切工作:高度和宽度是正确的,在画布上绘制的作品,并且在onload还火。在Firefox v3.6(OS X)中,启动浏览器后加载页面显示设置后高度/宽度不正确,drawImage()失败。(然而,onload处理程序会触发。)然而,再次加载页面会在设置和drawImage()工作后立即显示宽度/高度。Firefox似乎将数据URL的内容缓存为图像,并在同一会话中使用时立即可用。在Chrome v8(OS X)中,我看到与Firefox相同的结果:图像不能立即使用,但需要一些时间从数据URL异步“加载”。除了实验证明上述哪些浏览器有效或无效之外,我真的很喜欢这些应该如何表现的规范的链接。到目前为止,我的Google-fu还没有完成任务。安全玩耍对于那些不明白为什么上面可能有危险的人,要知道你应该使用这样的图像是安全的:// First create/find the imagevar img = new Image;// Then, set the onload handlerimg.onload = function(){  // Use the for-sure-loaded img here};// THEN, set the srcimg.src = '...';
查看完整描述

2 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

由于没有一个目前尚未发现这是怎么任何规格应该的行为,我们将不得不与它是如何满足并表现。以下是我的测试结果。


            | 是可用的图像数据| 在src之后进行onload回调设置

            | 设置src后?| 被更改仍然被调用?

------------ + ----------------------------- + ------- ------------------------------

Safari 5 | 是的| 是                

------------ + ----------------------------- + ------- ------------------------------

Chrome 8 | **没有**(第1页加载),但是| 是                

FireFox 3.6 | 之后是(缓存)|                                     

------------ + ----------------------------- + ------- ------------------------------

IE8 | 是(32kB数据限制)| 是         

------------ + ----------------------------- + ------- ------------------------------

IE9b | 是的| **没有**              

------------ + ----------------------------- + ------- ------------------------------

综上所述:


您不能假设在设置数据后立即可以使用图像数据-uri; 你必须等待这个onload事件。

由于IE9,您无法onload在设置之后设置处理程序src并期望调用它。

在这些建议“谨慎行事”(从上面的问题)是确保正确的行为的唯一途径。

如果有人能找到讨论这个的规格,我会乐意接受他们的回答。


查看完整回答
反对 回复 2019-07-26
?
慕少森

TA贡献2019条经验 获得超9个赞

在将控制权交还给浏览器的渲染引擎后,测试报告true在FF 4b9和Chromium 8.0.552.237中。我修改了这些部分:

img.onload = function(){   // put this above img.src = …
    document.getElementById('onload').innerHTML = 'yes';};img.src = img_src;…window.setTimeout(function () {   // put this inside setTimeout
    document.getElementById('wh').innerHTML = (img.height==img.width) && (img.height==128);}, 0);

更新:是的,我理解这个'答案'更像是一个评论,但只是想指出来。经过测试,我得到了可重复的结果:

  • 没有setTimeout,在这两种浏览器中,我false第一次打开页面时true才会遇到F5。明确清除缓存false后,重新加载后再说一遍。

  • 随着setTimeout宽度/高度测试总是evualuates true

在这两种情况下,只有在重新加载页面后,图像才会第一次显示。


查看完整回答
反对 回复 2019-07-26
  • 2 回答
  • 0 关注
  • 487 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信