JavaScript: как заставить Image () не использовать кеш браузера?

Если я загружаю URL-адрес nextimg вручную в браузере, он дает новое изображение при каждой перезагрузке. Но этот фрагмент кода показывает одно и то же изображение на каждой итерации draw().

Как заставить myimg не кешироваться?

<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>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
11
0
30 751
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Самый простой способ - прикрепить к концу постоянно меняющуюся строку запроса:

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

Некоторые люди предпочитают использовать для этого Math.random() вместо escape(new Date()). Но правильный способ, вероятно, - изменить заголовки, которые отправляет веб-сервер, чтобы запретить кеширование.

Дэн, вроде старый пост, но я определенно должен тебе пива за этот. Не совсем моя ситуация, но это дало мне отличную идею. Спасибо!

brmore 04.09.2009 22:57

Мне пришлось использовать его без конечной косой черты: var url = 'http;//.../something.png'+'?'+Math.random(), но он работает нормально! +1 за совет по заголовкам :)

Guillaume Gendre 05.09.2012 18:33

Здесь помогает Cache-Control: no-cache? Хотя я ценю изящный обходной путь, я не могу не задаться вопросом, лучшее ли это, что мы можем сделать прямо сейчас ... какие хаки мы тогда использовали в коде лунного посадочного модуля?

evilSnobu 26.10.2017 10:00

escape устарел, используйте вместо него encodeURI. См. w3schools.com/jsref/jsref_escape.asp

Ng Sek Long 25.09.2020 12:28

Вы не можете помешать ему полностью кэшировать изображение в Javascript. Но вы можете поиграть с src / адресом изображения, чтобы заставить его кешировать заново:

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

Вероятно, вы можете взять любое решение для кеширования Ajax и применить его здесь.

Ответ принят как подходящий

На самом деле это похоже на ошибку в браузере - вы можете подать в http://bugs.webkit.org, если он в Safari, или https://bugzilla.mozilla.org/ для Firefox. Почему я говорю о потенциальной ошибке браузера? Поскольку браузер понимает, что его не следует кэшировать при перезагрузке, он все же предоставляет вам кэшированную копию изображения, когда вы запрашиваете ее программно.

Тем не менее, вы уверены, что на самом деле что-нибудь рисуете? API Canvas.drawImage не будет ждать загрузки изображения и не требует отрисовки, если изображение не загрузилось полностью при попытке его использования.

Лучшая практика - это что-то вроде:

    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'

(Вы также можете просто передать draw в качестве аргумента для setTimeout вместо использования строки, что позволит избежать повторного анализа и компиляции одной и той же строки снова и снова.)

На самом деле есть кеши два, которые вам нужно обойти: один из них - это обычный HTTP-кеш, которого вы можете избежать, используя правильные заголовки HTTP в изображении. Но вы также должны запретить браузеру повторно использовать копию изображения в памяти; если он решит, что может это сделать, он никогда даже не дойдет до точки запроса своего кеша, поэтому заголовки HTTP не помогут.

Чтобы предотвратить это, вы можете использовать либо изменяющуюся строку запроса, либо изменяющийся идентификатор фрагмента.

Подробнее см. Мой пост здесь.

Другие вопросы по теме