2012-08-10 145 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指令,以便瀏覽器的後續請求使用緩存(此處不保證 - 取決於瀏覽器/用戶設置)。