0

我有一个读取地图平铺图像的功能。我想跟踪某个图像是否已经被缓存。我正在使用这个线程中的这个函数:

function is_cached(src) {
    var image = new Image();
    image.src = src;

    return image.complete;
}

这工作得很好。但后来我需要做一些图像处理。为了将图像数据复制到画布并逐像素处理,我需要使用CanvasRenderingContext2D.drawImage(image, 0, 0). 但它让我感到困扰的是一个跨域错误。所以我可以添加一个image.crossOrigin = "*",它解决了这个问题,我可以写到画布上并进行我需要的图像处理。那一点看起来像这样:

  imageOutput.crossOrigin = "*"
  var demCtx;
  imageOutput.onload = function(){
    var c = document.createElement('canvas')
    c.width = c.height = 256
    demCtx = c.getContext('2d')
    demCtx.drawImage(imageOutput, 0, 0)
    var imageData = demCtx.getImageData(0, 0, 256, 256)
  }

出现的问题是,每次我运行包含这两位代码的较大函数时,该is_cached函数每次都返回 false,除了第一次。但我知道,即使is_cached返回 false,图像确实被缓存,因为它们以 0 延迟加载(而不是在调用新图像并且需要一些时间从服务器获取它时)。

为什么会.crossOrigin = "*"干扰.complete图像的状态?

这发生在 ObservableHQ 笔记本中。这可能与它有关吗?ObservaleHQ 有时会变得很奇怪。

ObservableHQ Notebook 有问题

getTileUrl您可以在底部的单元格中找到此代码。这个笔记本还没写完。Tile Previously Cached单击提交对输入的更改的地图后,您可以在该行看到缓存状态。

谢谢阅读。

4

1 回答 1

0

也许 fetch api 可以使用 param 强制缓存{cache:"force-cache"},但是应该按预期缓存图像。您可以获取图像并将其 blob 作为图像源传递。

替换你imageOutput.src

    imageOutput.src = URL.createObjectURL(await fetch(imageUrl, {cache:"force-cache"}).then(r => r.blob()));

制作您的getTileURL功能async,因为我们必须等待 fetch 和 blob 准备好作为图像源传递

  async function getTileURL(latArg, lngArg, zoomArg) {

使用 devtools 检查网络并查看来自磁盘缓存的平铺图像

编辑:

只需尝试您的原始代码并通过 devtools 检查网络。切片图像按预期缓存。所以不需要破解 fetch blob src。

于 2020-05-09T06:34:29.770 回答