Добавление img.crossOrigin = "*" мешает img.complete - PullRequest
0 голосов
/ 09 мая 2020

У меня есть функция, которая читает изображения фрагментов карты. Я хочу отслеживать, было ли уже кэшировано определенное изображение. Я использую эту функцию из этого потока :

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 с проблемой

Вы можете найти этот код в ячейке getTileUrl внизу. Этот блокнот еще не закончен. Вы можете увидеть кешированный статус в строке Tile Previously Cached после того, как вы щелкнете по карте отправки изменений во входные данные.

Спасибо за чтение.

1 Ответ

0 голосов
/ 09 мая 2020

Может быть, fetch api может принудительно кешировать с помощью параметра {cache:"force-cache"}, однако изображения должны кэшироваться должным образом. Вы можете получить изображение и передать его blob в качестве источника изображения.

замените imageOutput.src на

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

сделайте вашу getTileURL функцию async, поскольку мы должны ждать выборки и blob, чтобы быть готовым к передаче в качестве источника изображения

  async function getTileURL(latArg, lngArg, zoomArg) {

Используйте инструменты разработчика для проверки сети и просмотра изображений плиток, поступающих из кеша диска

редактировать:

просто попробуйте свой исходный код и проверьте сеть с помощью devtools. Как и ожидалось, изображения плиток кэшируются. Так что не нужно взламывать fetch blob sr c.

...