2008-10-03 15 views
10

Jeśli ręcznie wczytam adres URL nextimg w przeglądarce, nowe zdjęcie jest wyświetlane za każdym razem, gdy ponownie je ładuję. Ale ten fragment kodu pokazuje ten sam obraz w każdej iteracji draw().JavaScript: jak zmusić Image(), aby nie używał pamięci podręcznej przeglądarki?

Jak mogę zmusić myimg, aby nie był buforowany?

<html> 
    <head> 
    <script type="text/javascript"> 
     function draw(){ 
     var canvas = document.getElementById('canv'); 
     var ctx = canvas.getContext('2d'); 
     var rx; 
     var ry; 
     var i; 

     myimg = new Image(); 
     myimg.src = 'http://ohm:8080/cgi-bin/nextimg' 

     rx=Math.floor(Math.random()*100)*10 
     ry=Math.floor(Math.random()*100)*10 
     ctx.drawImage(myimg,rx,ry); 
     window.setTimeout('draw()',0); 
     } 
    </script> 
    </head> 
    <body onload="draw();"> 
    <canvas id="canv" width="1024" height="1024"></canvas> 
    </body> 
</html> 

Odpowiedz

5

To rzeczywiście brzmi jak błąd w przeglądarce - możesz złożyć plik pod http://bugs.webkit.org, jeśli jest w Safari lub https://bugzilla.mozilla.org/ dla przeglądarki Firefox. Dlaczego mówię o potencjalnym błędzie przeglądarki? Ponieważ przeglądarka zdaje sobie sprawę, że nie powinna buforować przy ponownym ładowaniu, ale daje buforowaną kopię obrazu, gdy żądasz go programowo.

Czy powiedziałeś, że na pewno coś rysujesz? interfejs API Canvas.drawImage nie będzie czekać na załadowanie obrazu i nie zostanie narysowany, jeśli obraz nie został całkowicie załadowany podczas próby jego użycia.

Lepszym rozwiązaniem jest coś takiego:

var myimg = new Image(); 
    myimg.onload = function() { 
     var rx=Math.floor(Math.random()*100)*10 
     var ry=Math.floor(Math.random()*100)*10 
     ctx.drawImage(myimg,rx,ry); 
     window.setTimeout(draw,0); 
    } 
    myimg.src = 'http://ohm:8080/cgi-bin/nextimg' 

(można też po prostu przejść draw jako argument setTimeout, zamiast przy użyciu ciąg, który pozwoli zaoszczędzić ponownej analizy składniowej i kompilacji ten sam ciąg kółko.)

24

Najprostszym sposobem jest temblak ciągle zmieniającym kwerendy na koniec:

var url = 'http://.../?' + escape(new Date()) 

Niektórzy ludzie wolą używać Math.random() na tym, że zamiast escape(new Date()). Ale poprawną metodą jest prawdopodobnie zmiana nagłówków wysyłanych przez serwer WWW w celu uniemożliwienia buforowania.

+0

Dan, rodzaj starej poczty, ale na pewno jestem ci winien piwo na tym. Niezupełnie moja sytuacja, ale dał mi świetny pomysł. Dzięki! – brmore

+0

Musiałem użyć tego bez końcowego ukośnika: 'var url = 'http; //.../ something.png' + '?' + Math.random()', ale działa poprawnie! +1 dla poradnika headers :) –

+0

Piękno, zapomniałem o tej małej sztuczce! – JDandChips

7

Nie można tego powstrzymać od buforowania obrazu w całości w JavaScript. Ale można zabawka z src/adres obrazek, aby zmusić go do pamięci podręcznej na nowo:

[Image].src = 'image.png?' + (new Date()).getTime(); 

Prawdopodobnie można podjąć jakiekolwiek z rozwiązań pamięci podręcznej Ajax i stosować go tutaj.

0

W rzeczywistości istnieją dwie cache, które trzeba ominąć: jedną z nich jest zwykła pamięć podręczna HTTP, której można uniknąć, używając prawidłowych nagłówków HTTP na obrazie. Ale musisz również powstrzymać przeglądarkę przed ponownym użyciem kopii obrazu w pamięci; jeśli zdecyduje, że może to zrobić, to nigdy nie dojdzie nawet do pytania o pamięć podręczną, więc nagłówki HTTP nie pomogą.

Aby temu zapobiec, można użyć zmieniającego się kwerendy lub zmieniającego się identyfikatora fragmentu.

Zobacz mój wpis here po więcej szczegółów.

Powiązane problemy