使用同一网址的新图片刷新图片

IT技术 javascript image url refresh
2021-01-31 07:07:17

我正在访问我网站上的一个链接,每次访问时都会提供一个新图像。

我遇到的问题是,如果我尝试在后台加载图像,然后更新页面上的图像,图像不会改变——尽管它会在我重新加载页面时更新。

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

我需要强制刷新页面上的图像。有任何想法吗?

6个回答

尝试在 url 的末尾添加一个缓存破坏者:

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

这将在您创建图像时自动附加当前时间戳,并使浏览器再次查找图像而不是检索缓存中的图像。

此外,在其他地方重新显示相同的图像,稍后没有“缓存断路器”,仍然显示旧的缓存版本(至少在 Firefox 中)?和 # :(
2021-03-10 07:07:17
你可以用这个编写更少的代码: 'image.jpg?' + (+new Date())
2021-03-11 07:07:17
不是一个很好的解决方案,因为它会淹没缓存(本地和上游)。Aya 的回答有一个更好的方法来处理这个问题。
2021-03-17 07:07:17
为什么不 Math.random()
2021-03-18 07:07:17
Date.now()这个
2021-04-03 07:07:17

我已经看到关于如何做到这一点的答案有很多变化,所以我想我会在这里总结它们(加上我自己发明的第四种方法):


(1) 给 URL 添加唯一的 cache-busting 查询参数,如:

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

优点: 100% 可靠、快速且易于理解和实施。

缺点:完全绕过缓存,这意味着只要图像在视图之间没有变化,就会产生不必要的延迟和带宽使用可能会用许多完全相同图像的副本填充浏览器缓存(和任何中间缓存)!此外,需要修改图像 URL。

何时使用:在图像不断变化时使用,例如用于实时网络摄像头馈送。如果您使用此方法,请确保使用Cache-control: no-cacheHTTP 标头为图像本身提供服务!!! (通常这可以使用 .htaccess 文件进行设置)。否则,您将逐渐用旧版本的图像填充缓存!


(2) 将查询参数添加到仅在文件更改时更改的 URL,例如:

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

(这是 PHP 服务器端代码,但这里的重点只是将 ?m= [file last-modified time]查询字符串附加到文件名中)。

优点: 100% 可靠、快速且易于理解和实施,完美地保留了缓存优势。

缺点:需要修改图片 URL。此外,服务器需要做更多的工作 - 它必须访问文件上次修改时间。此外,需要服务器端信息,因此不适合用于检查刷新图像的纯客户端解决方案。

何时使用:当您想要缓存图像,但可能需要不时在服务器端更新它们而不更改文件名本身时。并且当您可以轻松确保将正确的查询字符串添加到 HTML 中的每个图像实例时。


(3) 使用 header 提供图像Cache-control: max-age=0, must-revalidate,并在 URL 中添加唯一的memcache -busting 片段标识符,例如:

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

这里的想法是缓存控制标头将图像放入浏览器缓存中,但立即将它们标记为陈旧,因此每次重新显示它们时,浏览器都必须检查服务器以查看它们是否已更改。这可确保浏览器的HTTP 缓存始终返回图像的最新副本。但是,浏览器通常会重用图像的内存副本(如果有的话),在这种情况下甚至不检查它们的 HTTP 缓存。为了防止这种情况,使用了片段标识符:比较内存中的图像src包括片段标识符,但在查询 HTTP 缓存之前它会被删除。(因此,例如,image.jpg#Aimage.jpg#B可能都从image.jpg浏览器的 HTTP 缓存中条目中显示,但是image.jpg#B永远不会使用image.jpg#A上次显示时的内存中保留的图像数据显示)。

优点:正确使用 HTTP 缓存机制,如果没有更改,则使用缓存的图像。适用于在添加到静态图像 URL 的查询字符串上阻塞的服务器(因为服务器永远不会看到片段标识符 - 它们仅供浏览器自己使用)。

缺点:依赖于浏览器在 URL 中带有片段标识符的图像的一些可疑(或至少记录不充分)行为(但是,我已经在 FF27、Chrome33 和 IE11 中成功测试了这一点)。仍然会为每个图像视图向服务器发送重新验证请求,如果图像很少更改和/或延迟是一个大问题,这可能是矫枉过正(因为即使缓存的图像仍然良好,您也需要等待重新验证响应) . 需要修改图像 URL。

何时使用:在图像可能频繁更改,或需要客户端间歇性刷新而无需服务器端脚本参与,但您仍希望获得缓存优势的情况下使用。例如,轮询每隔几分钟不定期更新图像的实时网络摄像头。或者,如果您的服务器不允许静态图像 URL 上的查询字符串,则使用 (1) 或 (2) 代替。

[编辑 2021:不再适用于最近的 Chrome 和 Edge:这些浏览器中的内部内存缓存现在忽略片段标识符(可能是因为切换到 Blink 引擎?)。但是请参阅下面的方法 (4),现在在这两种浏览器上特别容易得多,因此请考虑将此方法与 (4) 的简化版本相结合以覆盖这两种浏览器]。


(4) 使用 Javascript 强制刷新特定图像,首先将其加载到隐藏中<iframe>,然后调用location.reload(true)iframe 的contentWindow.

步骤是:

  • 将要刷新的图像加载到隐藏的 iframe 中。 [编辑 2021:对于 Chrome 和 Edge,加载带有<img>标签的 HTML 页面,而不是原始图像文件]。这只是一个设置步骤 - 如果需要,它可以在实际刷新之前很长时间完成。如果图像在这个阶段加载失败也没关系!

  • [编辑 2021:这一步现在在最近的 Chrome 和 Edge 中是不必要的]。完成后,将页面上或任何 DOM 节点中的任何位置(甚至存储在 javascript 变量中的页外节点)中该图像的所有副本清空。这是必要的,因为浏览器可能会显示来自陈旧内存副本的图像(IE11 尤其如此):您需要确保在刷新 HTTP 缓存之前清除所有内存副本。如果其他 javascript 代码正在异步运行,您可能还需要防止该代码同时创建要刷新图像的新副本。

  • 打电话iframe.contentWindow.location.reload(true)这会true强制绕过缓存,直接从服务器重新加载并覆盖现有的缓存副本。

  • [编辑 2021:这一步现在在最近的 Chrome 和 Edge 中是不必要的 - 在这些浏览器上,现有图像将在上一步之后自动更新!]重新加载完成后,恢复空白图像。他们现在应该显示来自服务器的新版本!

对于同域图片,您可以直接将图片加载到 iframe 中。 [编辑 2021:不在 Chrome、Edge 上]。对于跨域图像,您必须从您的域中加载一个 HTML 页面页面<img>标签中包含该图像,否则在尝试调用iframe.contentWindow.reload(...). [也为 Chrome 和 Edge 执行此操作]。

优点:就像你希望DOM 拥有的 image.reload() 函数一样工作!允许图像正常缓存(如果需要,即使在未来的到期日期,从而避免频繁的重新验证)。允许您仅使用客户端代码刷新特定图像,而无需更改当前页面或任何其他页面上该图像的 URL。

缺点:依赖于 Javascript。不能 100% 保证在每个浏览器中都能正常工作(不过我已经在 FF27、Chrome33 和 IE11 中成功测试过)。相对于其他方法非常复杂。[编辑 2021:除非您只需要最近的 Chrome 和 Edge 支持,在这种情况下它会简单得多]。

何时使用:当您有一组想要缓存的基本静态图像时,但您仍然需要能够偶尔更新它们并立即获得更新发生的视觉反馈。(特别是当仅刷新整个浏览器页面不起作用时,例如在某些基于 AJAX 构建的 Web 应用程序中)。当方法 (1)-(3) 不可行时,因为(无论出于何种原因)您无法更改可能显示您需要更新的图像的所有 URL。(请注意,使用这 3 种方法将刷新图像,但如果另一个页面尝试在没有适当查询字符串或片段标识符的情况下显示该图像,它可能会显示旧版本)。

下面给出了以一种非常健壮和灵活的方式实现这一点的细节:

假设您的网站在 URL 路径处包含一个空白的 1x1 像素 .gif /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'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 数组 [success, width, height],那么您的代码可能如下所示:

// 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 进行一些更改。

@Emilios:oop,不,我不会:我意识到一个简单的修复(现在包含在我的答案中)允许它也适用于跨域图像(前提是您可以在服务器上放置服务器端脚本)。
2021-03-10 07:07:17
@Emilios:...另外,我不明白您对必须重新加载整个页面的评论。方法 (3) 和 (4) 都可以在客户端 javascript 中实现,除了您正在刷新的一张图像外,无需重新加载任何内容。对于方法 (3),这只是意味着使用 javascript 将图像的 'src' 属性从(例如)image.jpg#123更改为image.jpg#124(或其他任何内容,只要 '#' 之后的位发生变化)。你能澄清一下你正在重新加载的是什么,为什么?
2021-03-26 07:07:17
@Emilios:您确实可以将外部(跨域)内容加载到 iframe 中……但是您无法contentWindow通过 javascript访问它来进行reload(true)调用,这是该方法的关键部分……所以不,方法 (4 ) 不适用于跨域内容。好眼力; 我会更新“缺点”以包含它。
2021-04-01 07:07:17
我喜欢方法 4 的想法,但是您不能使用 Iframe 加载外部内容,对吗?我目前在单页 Web 应用程序中使用方法 3,但我不喜欢您必须重新加载整个页面才能获取新图像的事实,即使模板的 HTML 被重新加载。
2021-04-08 07:07:17
@pseudosavant:不幸的是,我在大约 17 个月后才注意到这一点,但很抱歉不得不告诉您,您对我的代码所做的编辑严重损坏。(公平地说,我认为我最初拥有的回调代码也不正确)。我现在已经广泛地重写了第 (4) 部分,包括解释和代码。你以前的代码从来没有消隐图像(所以它可能会以奇怪的方式失败,特别是在 IE 中,尤其是如果图像在多个地方显示),但更糟糕的是它在开始完全重新加载后立即删除了 iframe,这可能意味着它会只能间歇性地工作或根本不工作。对不起!
2021-04-09 07:07:17

作为替代...

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-storeChrome 也需要

有几个头缓存。其实我不是很懂英文,你能告诉我我应该用哪一个吗?!我想要一些不只缓存更改的照片(如验证码)并缓存其他内容的东西。所以Cache-Control: max-age=0, must-revalidate对我有好处吗?
2021-03-14 07:07:17
为了避免对象创建和/​​或方法调用的开销,您可以使用递增整数作为缓存破坏者: newImage.src = "http://localhost/image.jpg#" + i++;
2021-03-17 07:07:17
这里涉及两个缓存:浏览器​​的常规 HTTP 缓存和它最近显示的图像的内存缓存。后者的内存缓存由 fullsrc属性索引,因此添加唯一的片段标识符可确保图像不会简单地从内存中提取。但是片段标识符不会作为 HTTP 请求的一部分发送,因此将正常使用常规 HTTP 缓存。这就是为什么这种技术有效。
2021-03-19 07:07:17
伟大的!在尝试加载延迟加载的网络图像很多时间后,我刚刚通过应用您的解决方案解决了它(使用“#”,使用“?”对我不起作用)。非常感谢!!!
2021-03-26 07:07:17
它对我不起作用。在我的情况下,唯一不同的是我有一个控制器操作的 URL,它从数据库中检索 img。我有控制器动作的其他参数,所以我将它添加为“......&convert=true&t=”+ new Date().getTime(); 和 "......&convert=true#" + new Date().getTime();。有什么我做错了吗?
2021-04-05 07:07:17

创建新图像后,您是否从 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);
}

使其工作后,如果仍然存在问题,则可能是其他答案所讨论的缓存问题。

<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 秒内重新加载。我在带有不同类型家庭安全摄像头的页面上使用它。