【问题标题】:Update CSS background-image Only When Source Image Changes Using Javascript仅在使用 Javascript 更改源图像时更新 CSS 背景图像
【发布时间】:2017-11-29 21:35:42
【问题描述】:

只有在服务器中更改源图像时,是否可以在 Javascript 中更新 "backgound-image: \"<some-url>\" 中传入的 url 指向的 CSS 图像。 IE。缓存图像,然后在需要重新加载时从服务器检索图像并将其与缓存的图像进行比较。然后,仅在更新时重新加载它。我知道为了通过Javascript刷新CSS中的图像,图像必须在“?”之后有不同的字符串。在图像源中,一种方法是在“?”之后使用Date.getTime 方法返回的当前时间。例如。 (我从这里https://stackoverflow.com/a/1077051/7000599得到这个方法):

$(".some-css-class").css("backgound-image", "url(" + "\"" + some_source + "?" + new Date().getTime() + "\"" + ")");

但是,当我需要更新background-image 时,我想调用上述逻辑,仅当它检测到图像已更改时。那么有没有办法检测到这种变化呢?

【问题讨论】:

  • 您需要创建一个计时器,每隔几秒对图像执行一次 XMLHTTP 请求,并检查图像的最后修改日期,然后将其与文件保存时间的缓存副本进行比较最后修改。这似乎是一项非常大量的工作,而且相当密集。为什么您需要更新图像?您不能确保访问者从一开始就不会缓存该图像吗?
  • @ObsidianAge 不,但是例如,如果我在某处设置了 onInterval 事件来更新照片,我希望事件处理程序仅在缓存图像!= 新图像时更新图像,所以,例如,我不会看到图像闪烁,除非它真的在更新!
  • 检测它的唯一方法是加载它....或者您有一个服务告诉您它已更改。所以要么你在每次调用时打破缓存(查询字符串或没有缓存头),要么你写一些东西说图像发生了变化。

标签: javascript jquery css image caching


【解决方案1】:

给每个图像一个唯一的 id,然后每隔一段时间轮询服务器以查看是否有新的 id,如果有,则更改底层图像。

【讨论】:

    【解决方案2】:

    您可以将 API 添加到服务器端,该 API 返回图像内容的一些哈希值。因此,当您第一次放置图像时 - 在“?”之后添加特定图像的哈希值。

    $(".come-css-class").css("backgound-image", "url(" + "\"" + some_source + "?" + imageHash + "\"" + ")");
    

    不时调用 hash API 并替换 background-image 属性。当图像将在服务器上更新时 - 它会返回新的哈希值 - 所以 css 将重新加载图像。

    【讨论】:

    • Lmao,我只是想了一个类似的答案!不过谢谢!
    • 我可以从 Javascript 端生成加载图像的哈希吗?
    • 可以,但会出错,因为你会一次又一次地通过网络获得相同的图像,只是为了确保它的内容不会改变。
    • 我决定依靠使用en.wikipedia.org/wiki/HTTP_ETag 来检测内容是否发生变化。如果源更新,ETag 将更新!
    【解决方案3】:

    要通过 JavaScript 本身自动更新图像(不依赖任何后端脚本),您需要定期轮询服务器以检查修改日期是否大于图像的缓存副本。如果是这种情况,您将需要刷新页面。

    这将类似于以下内容:

    var previous = null;
    var current = null;
    var image_url = 'IMAGE URL';
    setInterval(function() {
      var req = new XMLHttpRequest(); // Poll the server
      req.open("HEAD", image_url, false);
      req.send(null);
      if (req.status == 200) {
        current = req.getResponseHeader('Last-Modified'); // Get modification time
      }
      if (previous && current && previous !== current) { // If it's been modified
        location.reload(); // Refresh
      }
      previous = current; // Store the 'new' image information
      $(".come-css-class").css("background-image", "url(" + "\"" + image_url + "\""); // Update the image
    }, 2000); // Repeat every two seconds
    

    另请注意,您在问题中将其称为 backgound-image。您需要确保将其命名为 background-image 才能正常运行。

    希望这会有所帮助! :)

    【讨论】:

      【解决方案4】:

      类似于@Nosyara 的回复评论,我认为到目前为止我发现的解决此问题的更好方法是使用 HTTP 标头 ETag 来检测源图像(或文件)是否从最后缓存的文件。我认为@ObsidianAge 的答案也可以工作(即使用Last-Modified 标头),但由于某种原因,当源图像(或文件)发生更改时它不会显示任何更改。我做了一个简单的本地 Apache 服务器和简单的网页,带有 Javascript onInterval 事件到 console.log,无论文件是否已更改,但似乎并非如此。所以显然ETag 是一种方法。这是解释其用途的维基百科页面(它也有其他用途):https://en.wikipedia.org/wiki/HTTP_ETag

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-23
        相关资源
        最近更新 更多