Обновите изображение с помощью нового 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

Мне нужно принудительно обновить только это изображение на странице. Любые идеи?

Ответы

Ответ 1

То, что я закончил, - это предоставить серверу любой запрос на изображение в этом каталоге на источник, который я пытался обновить. Затем у меня был таймер, добавив число в конец имени, чтобы 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

Попробуйте добавить кэш-адрес в конце URL-адреса:

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

При создании изображения автоматически добавляется текущая временная метка, и она заставит браузер снова искать изображение вместо того, чтобы извлекать его в кеш.

Ответ 3

Я видел много вариаций в ответах на то, как это сделать, поэтому я подумал, что я их суммирую здесь (плюс добавьте четвертый метод моего собственного изобретения):


(1) Добавьте к URL-адресу уникальный параметр запроса кэширования, например:

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

Плюсы: 100% надежный, быстрый и понятный и реализуемый.

Минусы: Обходит полностью кеширование, что означает ненужные задержки и использование полосы пропускания, когда изображение не изменяется между представлениями. Потенциально заполняет кеш браузера (и любые промежуточные кеши) множеством копий одного и того же изображения! Кроме того, требуется изменить URL изображения.

Когда использовать: Использовать, когда изображение постоянно изменяется, например, для подачи живой веб-камеры. Если вы используете этот метод, убедитесь, что вы сами показываете изображения с помощью Cache-control: no-cache HTTP-заголовков!!! (Часто это можно настроить с помощью файла .htaccess). В противном случае вы будете постепенно заполнять кеширование старыми версиями изображения!


(2) Добавьте параметр запроса к URL-адресу, который изменяется только тогда, когда файл работает, например:

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

(Этот PHP-серверный код, но важным здесь является то, что к имени файла добавляется запрос с номером m = [файл с последним измененным временем]).

Плюсы: 100% надежный, быстрый и удобный для понимания и реализации, а также отлично сохраняет преимущества кеширования.

Минусы: Требуется изменить URL-адрес изображения. Кроме того, для сервера требуется немного больше работы - он должен получить доступ к времени последнего изменения файла. Кроме того, требуется серверная информация, поэтому она не подходит для чисто клиентского решения для проверки обновленного изображения.

Когда использовать:. Если вы хотите кэшировать изображения, но может потребоваться время от времени обновлять их на сервере, не изменяя имя файла. И когда вы можете легко убедиться, что правильная последовательность запросов добавляется к каждому экземпляру изображения в вашем HTML.


(3) Передайте изображения с заголовком Cache-control: max-age=0, must-revalidate и добавьте уникальный уникальный идентификатор фрагмента кэша к URL-адресу, например:

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

Идея здесь состоит в том, что заголовок управления кешем помещает изображения в кеш браузера, но сразу же маркирует их устаревшими, так что и каждый раз, когда они повторно отображаются, браузер должен проверить с сервером, чтобы увидеть, изменились ли они, Это гарантирует, что HTTP-кеш браузера всегда возвращает последнюю копию изображения. Тем не менее, браузеры часто будут повторно использовать копию памяти в памяти, если она есть, и даже не проверить их HTTP-кеш в этом случае. Чтобы предотвратить это, используется идентификатор фрагмента: сравнение изображения в памяти src включает в себя идентификатор фрагмента, но он удаляется перед запросом HTTP-кеша. (Так, например, image.jpg#A и image.jpg#B могут отображаться из записи image.jpg в кеше браузера HTTP, но image.jpg#B никогда не будет отображаться с использованием данных сохраненного изображения в памяти с момента последнего image.jpg#A отображается).

Плюсы: Правильно использует механизмы кэширования HTTP и использует кешированные изображения, если они не изменились. Работает на серверах, которые задерживаются на querystring, добавленном к URL статического изображения (поскольку серверы никогда не видят идентификаторы фрагментов - они предназначены только для использования браузерами).

Минусы: Оказывает несколько сомнительное (или, по крайней мере, плохо документированное) поведение браузеров, в отношении изображений с идентификаторами фрагментов в своих URL-адресах (однако, я успешно протестировал это в FF27, Chrome33, и IE11). По-прежнему отправляет запрос на повторную проверку на сервер для каждого изображения, что может быть чрезмерным, если изображения редко меняются и/или латентность является большой проблемой (так как вам нужно ждать ответа на повторную проверку, даже когда кешированное изображение по-прежнему хорошо), Требуется изменить URL-адреса изображений.

Когда использовать: Использовать, когда изображения могут часто меняться или должны периодически обновляться клиентом без участия на стороне сервера script, но там, где вам все еще нужно преимущество кеширования. Например, опрос живой веб-камеры, которая обновляет изображение нерегулярно каждые несколько минут. В качестве альтернативы используйте вместо (1) или (2), если ваш сервер не разрешает повторы на статических URL-адресах изображений.


(4) Принудительно обновить определенное изображение с помощью Javascript, сначала загрузив его в скрытый <iframe>, а затем вызывая location.reload(true) на iframe contentWindow.

Шаги:

  • Загрузите изображение, которое будет обновлено, в скрытый iframe. Это всего лишь шаг настройки - это можно сделать заблаговременно, если это необходимо. Даже неважно, если изображение не загружается на этом этапе!

  • После этого удалите все копии этого изображения на своей странице или в любом месте любых узлов DOM (даже внестраничных, хранящихся в переменных javascript). Это необходимо, потому что браузер может иначе отображать изображение из устаревшей копии в памяти (особенно это делает IE11): вам нужно убедиться, что все копии в памяти очищены до обновления кеша HTTP. Если другой javascript-код работает асинхронно, вам также может потребоваться, чтобы этот код не создавал новые копии обновляемого изображения в то же время.

  • Вызов iframe.contentWindow.location.reload(true). true заставляет обход кеша, перезагружается непосредственно с сервера и перезаписывает существующую кешированную копию.

  • После завершения повторной загрузки восстановите скрытые изображения. Теперь они должны отображать новую версию с сервера!

Для изображений с одинаковой областью вы можете напрямую загрузить изображение в iframe. Для междоменных изображений вам нужно вместо этого загружать HTML-страницу из своего домена, которая содержит изображение в теге <img>, иначе вы получите сообщение об ошибке "Отказано в доступе" при попытке вызвать iframe.contentWindow.reload(...).

Плюсы: Работает так же, как функция image.reload(), которую вы хотите, чтобы DOM! Позволяет делать снимки в обычном режиме (даже с датами истечения срока действия в будущем, если вы хотите их, что позволяет избежать частой повторной проверки). Позволяет обновлять определенное изображение без изменения URL-адресов для этого изображения на текущей странице или на любых других страницах, используя только клиентский код.

Минусы: Опирается на Javascript. Не гарантировано 100% работать в каждом браузере (я успешно тестировал это в FF27, Chrome33 и IE11). Очень сложно относительно других методов.

Когда использовать: Когда у вас есть коллекция в основном статических изображений, которые вы хотите кэшировать, но вы все равно должны иметь возможность периодически обновлять их и получать немедленную визуальную обратную связь, место. (Особенно, если просто обновить всю страницу браузера не будет работать, как в некоторых веб-приложениях, построенных на AJAX, например). И когда методы (1) - (3) невозможны, потому что (по какой-либо причине) вы не можете изменить все URL-адреса, которые могут потенциально отображать изображение, которое необходимо обновить. (Обратите внимание, что с использованием этих 3 методов изображение будет обновлено, но если другая страница затем попытается отобразить это изображение без соответствующего идентификатора запроса или фрагмента, вместо него может отображаться более старая версия).

Ниже приведены подробные сведения об этом в феерической и гибкой форме:

Предположим, что ваш сайт содержит пустой 1x1 пиксель .gif по пути URL /img/1x1blank.gif, а также имеет следующий однострочный PHP скрипт (требуется только для принудительного обновления для междоменных изображений и может быть переписан на любом языке сценариев на стороне сервера, конечно) на пути URL /echoimg.php:

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

Затем, здесь реалистичная реализация того, как вы можете сделать все это в Javascript. Это выглядит немного сложнее, но есть много комментариев, и важная функция - просто forceImgReload() - первые два только пустых и непустых изображения и должны быть разработаны для эффективной работы с вашим собственным 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 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 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 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));
}

Заключительное примечание. Хотя этот раздел посвящен изображениям, он потенциально применим и к другим типам файлов или ресурсов. Например, предотвращение использования устаревших файлов script или css или, возможно, даже обновление обновленных PDF-документов (с использованием (4) только при настройке для открытия в браузере). Метод (4) может потребовать некоторых изменений в вышеупомянутом javascript, в этих случаях.

Ответ 4

В качестве альтернативы...

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-Since или If-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.

Ответ 5

После создания нового изображения вы удаляете старое изображение из 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

Один из ответов заключается в том, чтобы хакерство добавить некоторый параметр запроса запроса, как это было предложено.

Лучший ответ - испустить несколько дополнительных опций в вашем 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 не является действительно необходимым для современных современных браузеров/кешей, но может помочь с некоторые жестокие сломанные старые реализации.

Ответ 7

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')" />

Ответ 8

document.getElementById("img-id").src = document.getElementById("img-id").src

установите собственный src как src.

Ответ 9

У меня было требование: 1) не может добавить ?var=xx к изображению 2) он должен работать в междоменном

Мне действительно нравится вариант # 4 в этом ответе с одним, но:

  • у него есть проблемы с надежной работой с crossdomain (и это требует прикосновения к серверному коду).

Мой быстрый и грязный способ:

  • Создать скрытый iframe
  • Загрузить текущую страницу (да, целая страница)
  • iframe.contentWindow.location.reload(true);
  • Повторно установите источник изображения

Здесь

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-события.

Ответ 10

Следующий код полезен для обновления изображения при нажатии кнопки.

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')" />

Ответ 11

Попробуйте использовать бесполезную цепочку, чтобы сделать ее уникальным 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);
}

Ответ 12

Я решил эту проблему, отправив данные через сервлет.

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">

Ответ 13

Вот мое решение. Это очень просто. Планирование кадров может быть лучше.

<!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>

Ответ 14

Сильно основанный на коде Doin # 4, приведенный ниже пример упрощает этот код, используя document.write вместо src в iframe для поддержки CORS. Также основное внимание уделяется отключению кеша браузера, а не перезагрузке каждого изображения на странице.

Ниже написано в typescript и использует библиотеку обещаний angular $q, просто fyi, но должен быть достаточно легким для переноса на ванильный javascript. Метод предназначен для жизни внутри класса 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;
    }

Ответ 15

<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 секунду. Я использую это на странице с домашними камерами безопасности различного типа.

Ответ 16

Нет необходимости в махинациях new Date().getTime(). Вы можете обмануть браузер, имея невидимое фиктивное изображение и используя jQuery.load(), затем каждый раз создавая новое изображение:

<img src="" id="dummy", style="display:none;" />  <!-- dummy img -->
<div id="pic"></div>

<script type="text/javascript">
  var url = whatever;
  // You can repeat the following as often as you like with the same url
  $("#dummy").load(url);
  var image = new Image();
  image.src = url;
  $("#pic").html("").append(image);
</script>

Ответ 17

Я использовал нижеследующую концепцию первого связывания изображения с ложным (буфером) url и последующим связыванием его с действительным URL-адресом.

imgcover.ImageUrl = ConfigurationManager.AppSettings["profileLargeImgPath"] + "Myapp_CoverPic_" + userid + "Buffer.jpg";

imgcover.ImageUrl = ConfigurationManager.AppSettings["profileLargeImgPath"] + "Myapp_CoverPic_" + userid + ".jpg";

Таким образом, я заставляю браузер обновляться с помощью действительного URL-адреса.