2012-08-10 143 views
9

我想克隆随机生成的图像。 尽管我使用的是完全相同的url,但加载了不同的图像。 (在Chrome和Firefox中测试)用javascript强制图像缓存

我无法更改图像服务器,因此我正在寻找纯javascript/jQuery解决方案。

你如何强制浏览器重用第一张图片?

火狐: Firefox Demo

铬: Chrome Demo

试一试(也许你需要重新加载几次看到它)

代码: http://jsfiddle.net/TRUbK/

$("<img/>").attr('src', img_src) 
$("<div/>").css('background', background) 
$("#source").clone() 

演示: http://jsfiddle.net/TRUbK/embedded/result/

+0

抛开一些随机问题,如果你设法让这个工作起作用,那么当你开始使用图像数据时,你仍然会遇到问题,因为[图像来自不同的域](http ://stackoverflow.com/questions/9972049/cross-origin-data-in-html5-canvas)。预计每个规范的错误:http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#security-with-canvas-elements – 2012-08-20 18:14:31

回答

6

如果不是你的图像服务器,你不能更改图像服务器,但你可以在你自己的服务器上写一些东西来处理它。

第一次写东西在您选择的服务器端语言(PHP,ASP.NET,等等)是:

  1. 命中http://a.random-image.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes和下载它。您以两种方式之一生成密钥。要么得到整个事情的散列(MD5应该没问题,这不是一个与安全有关的用途,所以担心它现在太弱而且不适用)。或者获得图像的大小 - 后者可能有一些重复项,但生成速度更快。
  2. 如果图像尚未存储,请将其保存在使用该密钥作为其文件名的一部分的位置,并将内容类型另存为另一部分(如果存在JPEG和PNG混合)
  3. 回应带有下一阶段的URI的XML或JSON响应。

在您的客户端代码中,您通过XmlHttpRequest命中该URI以获取用于图像的URI。如果你想要一个新的随机的,再次点击第一个URI,如果你想要两个或更多的地方相同的图像,使用相同的结果。

该URI命中像http://yourserver/storedRandImage?id=XXX这样的其中XXX是关键(散列或大小如上所述)。该处理程序查找图像的存储副本,并将文件沿正确的内容类型发送到响应流。

这在技术上很容易,但可能的问题是合法的,因为您将图像的副本存储在另一台服务器上,您可能不再符合与发送随机服务的协议条款图片。

+0

这种做法是一个聪明但它并没有解决我的问题,图像本身是由第三方提供的服务,并通过他们的JavaScript库包含并登录(饼干)相关的。(我使用的随机-image.net仅用于演示) – jantimon 2012-08-16 09:43:48

+0

由于你的应用程序的用户登录到他们的?不会在那个工作,否:( – 2012-08-16 10:06:52

+0

因为不会有一个工作的解决方案,因为我脑海中以最多的选票奖励赏金。谢谢你的努力! – jantimon 2012-08-22 17:21:22

1

从您的随机图像生成器脚本发送的标头包含一个Cache-Control: max-age=0声明,它实际上告诉浏览器不要缓存图像。

如果您希望缓存结果,您需要修改图像生成器脚本/服务器以发送适当的缓存标头。

您还需要确保URL保持不变(因为有大量参数被传递,所以我没有看这方面的内容)。

+0

我不能更改图像标题,因为我不拥有图像服务器。网址是一样的。 – jantimon 2012-08-10 19:01:44

+0

@Ghommey那么你可能没有选择那么。这就是告诉浏览器应该如何缓存该项目。 – 2012-08-10 19:05:41

+0

为什么在第一次克隆之后它会工作? – jantimon 2012-08-10 19:12:07

0

告诉它停下来得到一个随机的形象,似乎工作您想要的方式,当我加入这个第三更换电话:

// Get the canvas element. 
var background = ($("#test").css('background-image')), 
img_src = background.replace(/^.+\('?"?/, '').replace(/'?"?\).*$/, '').replace(/&fromrandomrandomizer=yes/,'') 
+0

谢谢,但给定的网址只是一个例子,我想有随机图像,所以不幸的是这种方法不适合我。 – jantimon 2012-08-10 19:13:00

+0

但我只是删除随机图像部分当克隆。这是该过程的一部分,并不是说你不能使用随机图像。所以一旦生成原始图像,在克隆过程中就不会获得随机图像。 – Dameo 2012-08-10 19:16:54

+0

复制的图像应该像以前的随机图像一样。 – jantimon 2012-08-11 11:55:42

0

尝试:

var myImg = new Image(); 
myImg.src = img_src; 

然后追加“myImg”到你想要的地方:

$(document).append(myImg); 
+0

谢谢,但它不起作用。重新载入以下页面数次:http://jsfiddle.net/9ykXq/embedded/result/ – jantimon 2012-08-10 19:20:46

1

首先,你可以在网上“强制”任何东西。如果你需要强制一些东西,那么Web开发对你来说就是错误的媒介。

你可以尝试的是使用canvas element复制图像。示例请参见https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images

+2

请不要告诉我我能做什么,不能强制!我一直在网站开发中使用部队。如果你愿意,我可以教你。 – 2012-08-16 08:59:59

+4

@ j-man86你没有强迫任何东西。你只是做了一些碰巧在你测试过的所有场景中工作的东西(甚至可能有意无视那些你知道它不起作用的东西)。将一件事情命名为“强迫”,我可以指出一个不可行的场景(是的,这些场景可能不太可能,甚至是缓和的,但这不会改变你的“强迫”行不通的事实,因此它不是“强迫”)。 – RoToRa 2012-08-16 09:09:33

+0

谢谢@RoToRa这工作对Firefox,但不是镀铬:( http://jsfiddle.net/VT8c5/ – jantimon 2012-08-16 09:47:32

0

我这样做是与你的提琴手脚本和每次

#test { 
background:url(http://a.random-image.net.nyud.net/handler.aspx?username=chaosdragon&randomizername=goat&random=292.3402&fromrandomrandomizer=yes); 
width: 150px; 
height: 150px; 

}

注域名后.nyud.net得到了相同的图像。

1

您可以尝试保存图像的base64表示。

将图像加载到隐藏的div/canvas中,然后将其转换为base64。 (我不确定是否可以隐藏画布,也不能使用html4标签来传输img) 现在,您可以将“字符串化”图像存储在cookie中,并无限次地使用它...

1

似乎有两种解决方法:

  1. 如果你去的帆布方法,看看你是否能得到加载到Canvas本身的图像,这样就可以处理图像数据,而不是直接做第2个HTTP请求的图像。您可以将图像数据直接送入第二个画布。
  2. 如果您要构建代理,您可以让代理移除No-Cache指令,以便浏览器的后续请求使用缓存(此处不保证 - 取决于浏览器/用户设置)。