web-dev-qa-db-ja.com

同じURLで新しい画像を使用して画像を更新する

私は私のサイト上のリンクにアクセスしています。リンクはアクセスされるたびに新しい画像を提供します。

私が遭遇している問題は、私がバックグラウンドで画像をロードしてそれからページ上のものを更新しようとしても、画像は変わらないということです - それは私がページをリロードするとき更新されますが。

var newImage = new Image();
newImage.src = "http://localhost/image.jpg";

function updateImage()
{
if(newImage.complete) {
    document.getElementById("theText").src = newImage.src;
    newImage = new Image();
    number++;
    newImage.src = "http://localhost/image/id/image.jpg?time=" + new Date();
}

    setTimeout(updateImage, 1000);
}

FireFoxが見るヘッダー

HTTP/1.x 200 OK
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: image/jpeg
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Server: Microsoft-HTTPAPI/1.0
Date: Thu, 02 Jul 2009 23:06:04 GMT

ページ上のその画像だけを強制的に更新する必要があります。何か案は?

294
QueueHammer

私がやってしまったのは、サーバーがそのディレクトリのイメージに対するリクエストを更新しようとしているソースにマッピングすることでした。それから、DOMが新しいイメージとしてそれを見てロードするように、私のタイマーに名前の最後に数字を追加させました。

例えば。

http://localhost/image.jpg
//and
http://localhost/image01.jpg

同じ画像生成コードを要求しますが、ブラウザにとっては異なる画像のように見えます。

var newImage = new Image();
newImage.src = "http://localhost/image.jpg";
var count = 0;
function updateImage()
{
    if(newImage.complete) {
        document.getElementById("theText").src = newImage.src;
        newImage = new Image();
        newImage.src = "http://localhost/image/id/image" + count++ + ".jpg";
    }
    setTimeout(updateImage, 1000);
}
2
QueueHammer

URLの最後にキャッシュブレーカーを追加してみてください。

newImage.src = "http://localhost/image.jpg?" + new Date().getTime();

これにより、イメージを作成しているときに現在のタイムスタンプが自動的に追加され、ブラウザはキャッシュ内のイメージを取得するのではなく、イメージを再度検索するようになります。

312

私はこれを行う方法の答えに多くのバリエーションを見てきましたので、ここでそれらを要約すると思いました(さらに、自分の発明の4番目の方法を追加します):


(1)次のような一意のキャッシュ無効化クエリパラメータをURLに追加します。

newImage.src = "image.jpg?t=" + new Date().getTime();

長所: 100%信頼性が高く、素早く簡単に理解して実装できます。

短所:キャッシュを完全にバイパスします。つまり、ビュー間でイメージが変更されない場合は、不要な遅延と帯域幅の使用を意味します。ブラウザーのキャッシュ(および中間キャッシュ)を、まったく同じイメージの多数のコピーで潜在的に埋めます!また、画像のURLを変更する必要があります。

使用する場合:ライブWebカメラフィードなど、画像が常に変化している場合に使用します。このメソッドを使用する場合は、必ずCache-control: no-cache HTTPヘッダーで画像自体を提供してください!!!(多くの場合、これは.htaccessファイル)。そうしないと、古いバージョンの画像でキャッシュが徐々にいっぱいになります!


(2)ファイルが変更する場合にのみ変更されるクエリパラメータをURLに追加します。例:

echo '<img src="image.jpg?m=' . filemtime('image.jpg') . '">';

(これはPHPサーバー側コードですが、ここで重要な点は、?m =[file last-modified time]クエリ文字列がファイル名に追加されます)。

長所: 100%の信頼性、迅速かつ簡単に理解および実装、andはキャッシュの利点を完全に保持します。

短所:画像URLの変更が必要です。また、サーバーに対してもう少し作業が必要です。ファイルの最終変更時刻にアクセスする必要があります。また、サーバー側の情報が必要なので、更新されたイメージをチェックするための純粋にクライアント側のみのソリューションには適していません。

使用する場合:イメージをキャッシュしたいが、ファイル名自体を変更せずにサーバー側で時々更新する必要がある場合。そして、正しいクエリ文字列がHTMLのすべての画像インスタンスに追加されることを簡単に確認できる場合。


(3)ヘッダーCache-control: max-age=0, must-revalidateで画像を提供し、次のような一意のmemcache-busting fragment identifierをURLに追加します。

newImage.src = "image.jpg#" + new Date().getTime();

ここでの考え方は、キャッシュ制御ヘッダーが画像をブラウザのキャッシュに入れますが、すぐに古いものとしてマークするため、再表示されるたびに、ブラウザはサーバーで変更を確認する必要があります。これにより、ブラウザのHTTPキャッシュは常に画像の最新のコピーを返します。ただし、ブラウザは多くの場合、画像のメモリ内コピーを再利用し、その場合はHTTPキャッシュもチェックしません。これを防ぐために、フラグメント識別子が使用されます。メモリ内イメージsrc 'sの比較にはフラグメント識別子が含まれますが、HTTPキャッシュをクエリする前に削除されます。 (たとえば、image.jpg#Aimage.jpg#Bは両方ともブラウザのHTTPキャッシュのimage.jpgエントリから表示される場合がありますが、image.jpg#Bはメモリ内の保持画像を使用して表示されることはありませんimage.jpg#Aが最後に表示されたときのデータ)。

長所: HTTPキャッシュメカニズムを適切に使用し、変更されていない場合はキャッシュされたイメージを使用します。静的なイメージURLに追加されたクエリ文字列を絞るサーバーで機能します(サーバーはフラグメント識別子を決して参照しないため、ブラウザー自身が使用するためです)。

短所: URLにフラグメント識別子を含む画像に関して、ブラウザのやや疑わしい(または少なくとも不十分に文書化された)動作に依存しています(ただし、FF27、Chrome33、およびIE11でこれをテストしました)。すべての画像ビューに対してサーバーに再検証リクエストを送信しますが、画像がめったに変更されない場合や遅延が大きな問題である場合はやり過ぎになる可能性があります(キャッシュされた画像がまだ良好な場合でも再検証応答を待つ必要があるため) 。画像のURLを変更する必要があります。

使用する場合:画像が頻繁に変更される場合、またはサーバー側のスクリプトを使用せずにクライアントが断続的に更新する必要がある場合に使用しますが、キャッシュの利点が必要な場合に使用します。たとえば、数分ごとに不規則に画像を更新するライブWebカメラをポーリングします。または、サーバーが静的画像URLでクエリ文字列を許可しない場合は、(1)または(2)の代わりに使用します。


(4)最初に非表示の<iframe>にロードし、次にiframeのcontentWindowlocation.reload(true)を呼び出すことにより、Javascriptを使用して特定の画像を強制的に更新します。

手順は次のとおりです。

  • 更新する画像を非表示のiframeにロードします。これは単なるセットアップ手順です。必要に応じて、実際の更新のかなり前に実行できます。この段階で画像の読み込みに失敗しても問題ありません!

  • それが完了したら、ページまたはDOMノードの任意の場所(JavaScript変数に格納されているページ外のものも含む)で、そのイメージのすべてのコピーを空白にします。これは、ブラウザが古いメモリ内コピーから画像を表示する可能性があるために必要です(IE11は特にこれを行います):すべてを保証する必要がありますin-memoryHTTPキャッシュを更新する前に、コピーがクリアされます。他のJavaScriptコードが非同期で実行されている場合は、そのコードがその間にリフレッシュされるイメージの新しいコピーを作成しないようにする必要がある場合もあります。

  • iframe.contentWindow.location.reload(true)を呼び出します。 trueは、キャッシュバイパスを強制し、サーバーから直接リロードし、既存のキャッシュコピーを上書きします。

  • 終了したらre-loading、空白のイメージを復元します。サーバーから最新バージョンが表示されるはずです!

同じドメインの画像の場合、画像をiframeに直接読み込むことができます。クロスドメイン画像の場合、代わりに<img>タグに画像を含むHTMLページをドメインからロードする必要があります。 iframe.contentWindow.reload(...)を呼び出そうとすると、「アクセス拒否」エラーが発生します。

長所: image.reload()関数と同じように機能しますwishDOMにありました!画像を通常どおりにキャッシュできます(将来の有効期限が必要な場合でも、頻繁な再検証を回避できます)。クライアント側のコードのみを使用して、現在のページまたは他のページの画像のURLを変更せずに特定の画像を更新できます。

短所: Javascriptに依存しています。すべてのブラウザで正常に動作することが100%保証されるわけではありません(FF27、Chrome33、およびIE11でこれをテストしました)。他の方法に比べて非常に複雑です。

使用する場合:キャッシュしたい基本的に静的な画像のコレクションがあるが、時々それらを時々更新し、更新が行われたという視覚的なフィードバックを即座に得る必要がある場合。 (特に、たとえばAJAXに基づいて構築された一部のWebアプリのように、ブラウザページ全体を更新するだけでは機能しません)。また、(何らかの理由で)更新する必要がある画像を表示する可能性のあるすべてのURLを変更できないため、方法(1)〜(3)が実行可能でない場合。 (これらの3つの方法を使用すると画像が更新されますが、anotherページがその画像を表示しようとする場合 without適切なクエリ文字列またはフラグメント識別子、代わりに古いバージョンが表示される場合があります)。

妖精の堅牢で柔軟な方法でこれを実装する詳細を以下に示します。

WebサイトのURLパス/img/1x1blank.gifに空白の1x1ピクセルの.gifが含まれており、次の1行のPHPスクリプト(強制更新をcross-domain画像。もちろん、サーバー側のスクリプト言語で書き換え可能です)URLパス/echoimg.php

<img src="<?=htmlspecialchars(@$_GET['src'],ENT_COMPAT|ENT_HTML5,'UTF-8')?>">

次に、これをすべてJavaScriptで行う方法の現実的な実装を示します。少し複雑に見えますが、多くのコメントがあり、重要な関数は単にforceImgReload()です。最初の2つの画像は空白で空白がないため、独自のHTMLで効率的に動作するように設計する必要があります。あなたに最適です。それらの複雑さの多くはあなたのウェブサイトにとって不必要かもしれません:

// This function should blank all images that have a matching src, by changing their src property to /img/1x1blank.gif.
// ##### You should code the actual contents of this function according to your page design, and what images there are on them!!! #####
// Optionally it may return an array (or other collection or data structure) of those images affected.
// This can be used by imgReloadRestore() to restore them later, if that's an efficient way of doing it (otherwise, you don't need to return anything).
// NOTE that the src argument here is just passed on from forceImgReload(), and MAY be a relative URI;
// However, be aware that if you're reading the src property of an <img> DOM object, you'll always get back a fully-qualified URI,
// even if the src attribute was a relative one in the original HTML.  So watch out if trying to compare the two!
// NOTE that if your page design makes it more efficient to obtain (say) an image id or list of ids (of identical images) *first*, and only then get the image src,
// you can pass this id or list data to forceImgReload() along with (or instead of) a src argument: just add an extra or replacement parameter for this information to
// this function, to imgReloadRestore(), to forceImgReload(), and to the anonymous function returned by forceImgReload() (and make it overwrite the earlier parameter variable from forceImgReload() if truthy), as appropriate.
function imgReloadBlank(src)
{
  // ##### Everything here is provisional on the way the pages are designed, and what images they contain; what follows is for example purposes only!
  // ##### For really simple pages containing just a single image that's always the one being refreshed, this function could be as simple as just the one line:
  // ##### document.getElementById("myImage").src = "/img/1x1blank.gif";

  var blankList = [],
      fullSrc = /* Fully qualified (absolute) src - i.e. prepend protocol, server/domain, and path if not present in src */,
      imgs, img, i;

  for each (/* window accessible from this one, i.e. this window, and child frames/iframes, the parent window, anything opened via window.open(), and anything recursively reachable from there */)
  {
    // get list of matching images:
    imgs = theWindow.document.body.getElementsByTagName("img");
    for (i = imgs.length; i--;) if ((img = imgs[i]).src===fullSrc)  // could instead use body.querySelectorAll(), to check both tag name and src attribute, which would probably be more efficient, where supported
    {
      img.src = "/img/1x1blank.gif";  // blank them
      blankList.Push(img);            // optionally, save list of blanked images to make restoring easy later on
    }
  }

  for each (/* img DOM node held only by javascript, for example in any image-caching script */) if (img.src===fullSrc)
  {
    img.src = "/img/1x1blank.gif";   // do the same as for on-page images!
    blankList.Push(img);
  }

  // ##### If necessary, do something here that tells all accessible windows not to create any *new* images with src===fullSrc, until further notice,
  // ##### (or perhaps to create them initially blank instead and add them to blankList).
  // ##### For example, you might have (say) a global object window.top.blankedSrces as a propery of your topmost window, initially set = {}.  Then you could do:
  // #####
  // #####     var bs = window.top.blankedSrces;
  // #####     if (bs.hasOwnProperty(src)) bs[src]++; else bs[src] = 1;
  // #####
  // ##### And before creating a new image using javascript, you'd first ensure that (blankedSrces.hasOwnProperty(src)) was false...
  // ##### Note that incrementing a counter here rather than just setting a flag allows for the possibility that multiple forced-reloads of the same image are underway at once, or are overlapping.

  return blankList;   // optional - only if using blankList for restoring back the blanked images!  This just gets passed in to imgReloadRestore(), it isn't used otherwise.
}




// This function restores all blanked images, that were blanked out by imgReloadBlank(src) for the matching src argument.
// ##### You should code the actual contents of this function according to your page design, and what images there are on them, as well as how/if images are dimensioned, etc!!! #####
function imgReloadRestore(src,blankList,imgDim,loadError);
{
  // ##### Everything here is provisional on the way the pages are designed, and what images they contain; what follows is for example purposes only!
  // ##### For really simple pages containing just a single image that's always the one being refreshed, this function could be as simple as just the one line:
  // ##### document.getElementById("myImage").src = src;

  // ##### if in imgReloadBlank() you did something to tell all accessible windows not to create any *new* images with src===fullSrc until further notice, retract that setting now!
  // ##### For example, if you used the global object window.top.blankedSrces as described there, then you could do:
  // #####
  // #####     var bs = window.top.blankedSrces;
  // #####     if (bs.hasOwnProperty(src)&&--bs[src]) return; else delete bs[src];  // return here means don't restore until ALL forced reloads complete.

  var i, img, width = imgDim&&imgDim[0], height = imgDim&&imgDim[1];
  if (width) width += "px";
  if (height) height += "px";

  if (loadError) {/* If you want, do something about an image that couldn't load, e.g: src = "/img/brokenImg.jpg"; or alert("Couldn't refresh image from server!"); */}

  // If you saved & returned blankList in imgReloadBlank(), you can just use this to restore:

  for (i = blankList.length; i--;)
  {
    (img = blankList[i]).src = src;
    if (width) img.style.width = width;
    if (height) img.style.height = height;
  }
}




// Force an image to be reloaded from the server, bypassing/refreshing the cache.
// due to limitations of the browser API, this actually requires TWO load attempts - an initial load into a hidden iframe, and then a call to iframe.contentWindow.location.reload(true);
// If image is from a different domain (i.e. cross-domain restrictions are in effect, you must set isCrossDomain = true, or the script will crash!
// imgDim is a 2-element array containing the image x and y dimensions, or it may be omitted or null; it can be used to set a new image size at the same time the image is updated, if applicable.
// if "twostage" is true, the first load will occur immediately, and the return value will be a function
// that takes a boolean parameter (true to proceed with the 2nd load (including the blank-and-reload procedure), false to cancel) and an optional updated imgDim.
// This allows you to do the first load early... for example during an upload (to the server) of the image you want to (then) refresh.
function forceImgReload(src, isCrossDomain, imgDim, twostage)
{
  var blankList, step = 0,                                // step: 0 - started initial load, 1 - wait before proceeding (twostage mode only), 2 - started forced reload, 3 - cancelled
      iframe = window.document.createElement("iframe"),   // Hidden iframe, in which to perform the load+reload.
      loadCallback = function(e)                          // Callback function, called after iframe load+reload completes (or fails).
      {                                                   // Will be called TWICE unless twostage-mode process is cancelled. (Once after load, once after reload).
        if (!step)  // initial load just completed.  Note that it doesn't actually matter if this load succeeded or not!
        {
          if (twostage) step = 1;  // wait for twostage-mode proceed or cancel; don't do anything else just yet
          else { step = 2; blankList = imgReloadBlank(src); iframe.contentWindow.location.reload(true); }  // initiate forced-reload
        }
        else if (step===2)   // forced re-load is done
        {
          imgReloadRestore(src,blankList,imgDim,(e||window.event).type==="error");    // last parameter checks whether loadCallback was called from the "load" or the "error" event.
          if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
        }
      }
  iframe.style.display = "none";
  window.parent.document.body.appendChild(iframe);    // NOTE: if this is done AFTER setting src, Firefox MAY fail to fire the load event!
  iframe.addEventListener("load",loadCallback,false);
  iframe.addEventListener("error",loadCallback,false);
  iframe.src = (isCrossDomain ? "/echoimg.php?src="+encodeURIComponent(src) : src);  // If src is cross-domain, script will crash unless we embed the image in a same-domain html page (using server-side script)!!!
  return (twostage
    ? function(proceed,dim)
      {
        if (!twostage) return;
        twostage = false;
        if (proceed)
        {
          imgDim = (dim||imgDim);  // overwrite imgDim passed in to forceImgReload() - just in case you know the correct img dimensions now, but didn't when forceImgReload() was called.
          if (step===1) { step = 2; blankList = imgReloadBlank(src); iframe.contentWindow.location.reload(true); }
        }
        else
        {
          step = 3;
          if (iframe.contentWindow.stop) iframe.contentWindow.stop();
          if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
        }
      }
    : null);
}

次に、ページと同じドメインにある画像を強制的に更新するには、次のようにします。

forceImgReload("myimage.jpg");

他の場所(クロスドメイン)から画像を更新するには:

forceImgReload("http://someother.server.com/someimage.jpg", true);

より高度なアプリケーションとしては、サーバーに新しいバージョンをアップロードした後に画像をリロードし、アップロードと同時にリロードプロセスの初期段階を準備して、ユーザーに見えるリロード遅延を最小限に抑えることがあります。 AJAX経由でアップロードを実行していて、サーバーが非常に単純なJSON配列[成功、幅、高さ]を返している場合、コードは次のようになります。

// fileForm is a reference to the form that has a the <input typ="file"> on it, for uploading.
// serverURL is the url at which the uploaded image will be accessible from, once uploaded.
// The response from uploadImageToServer.php is a JSON array [success, width, height]. (A boolean and two ints).
function uploadAndRefreshCache(fileForm, serverURL)
{
  var xhr = new XMLHttpRequest(),
      proceedWithImageRefresh = forceImgReload(serverURL, false, null, true);
  xhr.addEventListener("load", function(){ var arr = JSON.parse(xhr.responseText); if (!(arr&&arr[0])) { proceedWithImageRefresh(false); doSomethingOnUploadFailure(...); } else { proceedWithImageRefresh(true,[arr[1],ar[2]]); doSomethingOnUploadSuccess(...); }});
  xhr.addEventListener("error", function(){ proceedWithImageRefresh(false); doSomethingOnUploadError(...); });
  xhr.addEventListener("abort", function(){ proceedWithImageRefresh(false); doSomethingOnUploadAborted(...); });
  // add additional event listener(s) to track upload progress for graphical progress bar, etc...
  xhr.open("post","uploadImageToServer.php");
  xhr.send(new FormData(fileForm));
}

最後の注意:このトピックは画像​​に関するものですが、他の種類のファイルやリソースにも適用される可能性があります。たとえば、古いスクリプトまたはcssファイルの使用を防止したり、更新されたPDFドキュメントを更新したりすることもできます(ブラウザー内で開くように設定されている場合のみ(4)を使用します)。方法(4)では、これらの場合、上記のJavaScriptを変更する必要があります。

197
Doin

の代替として...

newImage.src = "http://localhost/image.jpg?" + new Date().getTime();

...のようだ...

newImage.src = "http://localhost/image.jpg#" + new Date().getTime();

正しいCache-Controlヘッダを返したと仮定すれば、上流のキャッシュを迂回せずにブラウザのキャッシュを欺くには十分です。使えますが….

Cache-Control: no-cache, must-revalidate

...あなたはIf-Modified-SinceIf-None-Matchヘッダの恩恵を失います。

Cache-Control: max-age=0, must-revalidate

...実際に画像が変更されていない場合、ブラウザが画像全体を再ダウンロードしないようにする必要があります。 IE、Firefox、およびChromeでテスト済みで作業中。あなたが使用しない限り厄介にそれはSafariで失敗します...

Cache-Control: no-store

...これは上流のキャッシュを何百もの同一の画像で埋めるよりはまだ好ましいかもしれませんが、特にそれらがあなた自身のサーバ上で動いているときはそうです。 ;-)

更新(2014-09-28):Cache-Control: no-storeがChromeでも必要とされているようです。

175
Aya

新しい画像を作成したら、DOMから古い画像を削除して新しい画像に置き換えますか。

UpdateImageを呼び出すたびに新しい画像を取得することはできますが、それらをページに追加することはできません。

それにはいくつかの方法があります。このようなものはうまくいくでしょう。

function updateImage()
{
    var image = document.getElementById("theText");
    if(image.complete) {
        var new_image = new Image();
        //set up the new image
        new_image.id = "theText";
        new_image.src = image.src;           
        // insert new image and remove old
        image.parentNode.insertBefore(new_image,image);
        image.parentNode.removeChild(image);
    }

    setTimeout(updateImage, 1000);
}

それがうまくいった後で、まだ問題があるならば、それはおそらく他の答えが話しているようなキャッシュの問題です。

6
BaroqueBobcat

1つの答えは、提案されているようなgetクエリパラメーターをハックして追加することです。

より良い答えは、HTTPヘッダーでいくつかの追加オプションを発行することです。

Pragma: no-cache
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Cache-Control: no-cache, must-revalidate

過去の日付を指定すると、ブラウザーによってキャッシュされません。 Cache-ControlはHTTP/1.1で追加され、must-revalidateタグは、プロキシーが厄介な状況下でも古いイメージを提供しないことを示し、Pragma: no-cacheは現在の最新のブラウザー/キャッシュには実際には必要ありませんしかし、いくつかの壊れた古い実装の助けになるかもしれません。

4
Edward KMETT
function reloadImage(imageId)
{
   path = '../showImage.php?cache='; //for example
   imageObject = document.getElementById(imageId);
   imageObject.src = path + (new Date()).getTime();
}
<img src='../showImage.php' id='myimage' />

<br/>

<input type='button' onclick="reloadImage('myimage')" />
3
Mahmoud
document.getElementById("img-id").src = document.getElementById("img-id").src

独自のsrcをそのsrcとして設定します。

2
Hardik

それをユニークなURLにするために無価値なクエリ文字列を使ってみてください。

function updateImage()
{
    if(newImage.complete) {
        document.getElementById("theText").src = newImage.src;
        newImage = new Image();
        number++;
        newImage.src = "http://localhost/image.jpg?" + new Date();
    }

    setTimeout(updateImage, 1000);
}
1
Joel

1)画像に?var=xxを追加することはできません2)クロスドメインで動作するはずです

この答え の中の#4オプションがとても好きです

  • それはクロスドメインを確実に操作するのに問題があります(そしてそれはサーバーコードに触れる必要があります)。

私の早くて汚い方法は:

  1. 隠れたiframeを作成する
  2. 現在のページをそこにロードします(そうページ全体)
  3. iframe.contentWindow.location.reload(true);
  4. 画像ソースを自分自身に再設定します

ここにあります

function RefreshCachedImage() {
    if (window.self !== window.top) return; //prevent recursion
    var $img = $("#MYIMAGE");
    var src = $img.attr("src");
    var iframe = document.createElement("iframe");
    iframe.style.display = "none";
    window.parent.document.body.appendChild(iframe);
    iframe.src = window.location.href;
    setTimeout(function () {
        iframe.contentWindow.location.reload(true);
        setTimeout(function () {
            $img.removeAttr("src").attr("src", src);
        }, 2000);
    }, 2000);
}

ええ、私は知っています、setTimeout ...あなたはそれを適切なonload-eventsに変更する必要があります。

1
jazzcat

次のコードは、ボタンがクリックされたときに画像を更新するのに役立ちます。

function reloadImage(imageId) {
   imgName = 'vishnu.jpg'; //for example
   imageObject = document.getElementById(imageId);
   imageObject.src = imgName;
}

<img src='vishnu.jpg' id='myimage' />

<input type='button' onclick="reloadImage('myimage')" />
1
Codemaker

私はサーブレットを通してデータを送り返すことによってこの問題を解決しました。

response.setContentType("image/png");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.setDateHeader("Expires", 0);

BufferedImage img = ImageIO.read(new File(imageFileName));

ImageIO.write(img, "png", response.getOutputStream());

次に、そのページから、正しいイメージファイルを取得するためのパラメータをいくつか指定してサーブレットに渡します。

<img src="YourServlet?imageFileName=imageNum1">
0
tinymothbrain
<img src='someurl.com/someimage.ext' onload='imageRefresh(this, 1000);'>

その後、いくつかのJavaScriptで以下の

<script language='javascript'>
 function imageRefresh(img, timeout) {
    setTimeout(function() {
     var d = new Date;
     var http = img.src;
     if (http.indexOf("&d=") != -1) { http = http.split("&d=")[0]; } 

     img.src = http + '&d=' + d.getTime();
    }, timeout);
  }
</script>

そしてこれが何をするかは、画像がロードされるときに、1秒で再ロードされるようにスケジュールすることです。私はさまざまな種類の家庭用防犯カメラのあるページでこれを使っています。

0
J Fields

以下の例は、Doinの#4コードに大きく基づいており、CORSをサポートするためにsrc内のiframeの代わりにdocument.writeを利用してそのコードをかなり単純化しています。また、ページ上のすべての画像を再ロードするのではなく、ブラウザのキャッシュを無効にすることにのみ焦点を当てています。

以下はTypeScriptで書かれていて、angular$ q promiseライブラリを使っています。メソッドはTypeScriptクラス内に存在するように意図されています。

Iframeが再ロードを完了したときに解決されることを約束を返します。あまりテストされていませんが、私たちにはうまくいきます。

    mmForceImgReload(src: string): ng.IPromise<void> {
        var deferred = $q.defer<void>();
        var iframe = window.document.createElement("iframe");

        var firstLoad = true;
        var loadCallback = (e) => {
            if (firstLoad) {
                firstLoad = false;
                iframe.contentWindow.location.reload(true);
            } else {
                if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
                deferred.resolve();
            }
        }
        iframe.style.display = "none";
        window.parent.document.body.appendChild(iframe);
        iframe.addEventListener("load", loadCallback, false);
        iframe.addEventListener("error", loadCallback, false);
        var doc = iframe.contentWindow.document;
        doc.open();
        doc.write('<html><head><title></title></head><body><img src="' + src + '"></body></html>');
        doc.close();
        return deferred.promise;
    }
0
Victor

これが私の解決策です。とても簡単です。フレームスケジューリングはもっと良いかもしれません。

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">      
        <title>Image Refresh</title>
    </head>

    <body>

    <!-- Get the initial image. -->
    <img id="frame" src="frame.jpg">

    <script>        
        // Use an off-screen image to load the next frame.
        var img = new Image();

        // When it is loaded...
        img.addEventListener("load", function() {

            // Set the on-screen image to the same source. This should be instant because
            // it is already loaded.
            document.getElementById("frame").src = img.src;

            // Schedule loading the next frame.
            setTimeout(function() {
                img.src = "frame.jpg?" + (new Date).getTime();
            }, 1000/15); // 15 FPS (more or less)
        })

        // Start the loading process.
        img.src = "frame.jpg?" + (new Date).getTime();
    </script>
    </body>
</html>
0
Timmmm