应该立即将图像src设置为数据URL? [英] Should setting an image src to data URL be available immediately?

查看:125
本文介绍了应该立即将图像src设置为数据URL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的(脆弱的)JavaScript代码:

  var img = new Image; 
img.src =data:image / png; base64,...; //假定有效数据

//危险(?)试图在设置src后立即使用图像
console.log(img.width,img.height);
someCanvasContext.drawImage(img,0,0);

//危险(?)在设置src
后设置onload img.onload = function(){console.log('I ran!'); };

问题




  • 图片的宽度和高度应该立即正确吗?

  • 画布是否应立即绘制?

  • 应该调用 onload callback(在src被更改后设置)吗?



实验测试

我创建了一个简单测试页与类似的代码。在Safari中,我的第一个测试是通过在本地打开HTML页面( file:/// url)并从我的服务器加载它,结果显示一切正常:高度和宽度是正确,画布绘制工作, onload 也会触发。



在Firefox v3.6(OS X),启动浏览器后加载页面显示高度/宽度在设置后立即不正确, drawImage()失败。 (但是, onload 处理程序确实会触发。)但是,重新加载页面会在设置后立即显示宽度/高度正确,并且 drawImage( )工作。看起来,Firefox将数据URL的内容缓存为图像,并在同一会话中使用时立即可用。



在Chrome v8(OS X)中,I看到与Firefox中相同的结果:图像不是立即可用的,但需要一些时间从数据URL异步'加载'。



除了实验证明上面的浏览器做了什么或者哪些不起作用,我真的很喜欢关于这个应该如何表现的规范的链接。到目前为止,我的Google-fu还没有完成任务。



安全运行

对于那些不喜欢不明白为什么上述可能是危险的,知道你应该使用这样的图像是安全的:

  //首先创建/找到图片
var img = new图片;

//然后,设置onload处理函数
img.onload = function(){
//使用for-sure-loaded img here
};

//然后,设置src
img.src ='...';


解决方案

假设行为,我们必须对它的行为表示满意。以下是我的测试结果。

 
|是可以使用的图像数据|在src
|后加载回调集设置src后? |改变仍然被调用?
------------ + ----------------------------- + --- ----------------------------------
Safari 5 |是|是
------------ + ----------------------------- + - -----------------------------------
Chrome 8 | **没有**(第一页加载),但|是
FireFox 3.6 |之后是(缓存)|
------------ + ----------------------------- + --- ----------------------------------
IE8 |是(32kB数据限制)|是
------------ + ----------------------------- + - -----------------------------------
IE9b |是| **否**
------------ + ---------------------------- - + -------------------------------------

总结:


  • 您不能假设图像数据在设置完成后立即可用数据-URI;您必须等待 onload 事件。

  • 由于IE9,您不能设置 onload src 并期望它被调用后,c $ c>处理程序。

  • 中的建议安全地使用它 (从上面的问题)是确保正确行为的唯一方法。


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


Consider the following (fragile) JavaScript code:

var img = new Image;
img.src = "data:image/png;base64,..."; // Assume valid data

// Danger(?) Attempting to use image immediately after setting src
console.log( img.width, img.height );
someCanvasContext.drawImage( img, 0, 0 );

// Danger(?) Setting onload after setting src
img.onload = function(){ console.log('I ran!'); };

The Question(s)

  • Should the image width and height be correct immediately?
  • Should the canvas draw work immediately?
  • Should the onload callback (set after the src was changed) be invoked?

Experimental Tests
I created a simple test page with similar code. In Safari my first tests, both by opening the HTML page locally (file:/// url) and loading it from my server, showed everything working: the height and width is correct, the canvas draw works, and the onload also fires.

In Firefox v3.6 (OS X), loading the page after launching the browser shows that the height/width is not correct immediately after setting, drawImage() fails. (The onload handler does fire, however.) Loading the page again, however, shows the width/height being correct immediately after setting, and drawImage() working. It would appear that Firefox caches the contents of the data URL as an image and has it available immediately when used in the same session.

In Chrome v8 (OS X) I see the same results as in Firefox: the image is not available immediately, but takes some time to asynchronously 'load' from the data URL.

In addition to experimental proof of what browsers the above does or does not work, I'd really love links to specs on how this is supposed to behave. So far my Google-fu has not been up to the task.

Playing It Safe
For those who don't understand why the above might be dangerous, know that you should use images like this to be safe:

// First create/find the image
var img = new Image;

// Then, set the onload handler
img.onload = function(){
  // Use the for-sure-loaded img here
};

// THEN, set the src
img.src = '...';

解决方案

As no one has yet found any specifications about how this is supposed to behave, we will have to be satisfied with how it does behave. Following are the results of my tests.

            | is image data usable right  | does onload callback set after src
            |     after setting src?      |   is changed still get invoked?
------------+-----------------------------+-------------------------------------
Safari  5   |             yes             |                  yes                
------------+-----------------------------+-------------------------------------
Chrome  8   | **no** (1st page load), but |                  yes                
FireFox 3.6 |  yes thereafter (cached)    |                                     
------------+-----------------------------+-------------------------------------
IE8         |    yes (32kB data limit)    |                  yes         
------------+-----------------------------+-------------------------------------
IE9b        |             yes             |                 **no**              
------------+-----------------------------+-------------------------------------

In summary:

  • You cannot assume that the image data will be available right after setting a data-uri; you must wait for the onload event.
  • Due to IE9, you cannot set the onload handler after setting the src and expect it to be invoked.
  • The recommendations in "Playing it Safe" (from the question above) are the only way to ensure correct behavior.

If anyone can find specs discussing this, I will happily accept their answer instead.

这篇关于应该立即将图像src设置为数据URL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆