javascript Image() 下载时触发​​错误,原因不明

javascript Image() triggers errors when downloading, unclear why

我正在使用 Quasar 和此代码:

<template>
  <div class="q-pa-md">
    <div class="q-gutter-sm row items-start">
      <q-img
        v-for="pic in picObject"
        :key="pic.id"
        :src="pic"
        @error="reportError"
        style="height: 140px; width: 140px"
      >
        <template v-slot:default>
          <div class="absolute-bottom transparant-banner">This picture loaded ok.</div>
        </template>
        <template v-slot:error>
          <div class="absolute-full flex flex-center bg-dark" style="color: red">Cannot load image</div>
        </template>
      </q-img>
    </div>
  </div>
</template>
<script>

export default {
  components: {},
  data() {
    return {
      picObject: {  "2": "https://images.takeshape.io/86ce9525-f5f2-4e97-81ba-54e8ce933da7/dev/144069dc-7390-4022-aa0f-abba022d3a2f/spec.jpg?auto=compress%2Cformat", "3": "https://natureconservancy-h.assetsadobe.com/is/image/content/dam/tnc/nature/en/photos/prescribed_burn_oregon.jpg?crop=0,120,5760,3600&wid=1640&hei=1025&scl=3.5121951219512195", "4": "https://orig11.deviantart.net/1062/f/2015/315/9/6/abstract__7_by_thejsyve1-d9gciwk.jpg", "5": "https://natureconservancy-h.assetsadobe.com/is/image/content/dam/tnc/nature/en/photos/Brown_County_Hills_Leonetti.jpg?crop=33,0,1192,656&wid=4000&hei=2200&scl=0.29818181818181816", "6": "https://www.telegraph.co.uk/content/dam/Travel/galleries/travel/destinations/northamerica/usa/US%20national%20parks/AP84847745_Yosemite_General-xlarge.jpg", "7": "http://miriadna.com/desctopwalls/images/max/Papaverous-path.jpg", "8": "https://dehayf5mhw1h7.cloudfront.net/wp-content/uploads/sites/183/2016/09/15173325/Brown_County_Indiana_Estados_Unidos_2012-10-14_DD_10.jpg", "9": "https://s-media-cache-ak0.pinimg.com/originals/19/e9/58/19e9581dbdc756a2dbbb38ae39a3419c.jpg", "12": "https://cdn.pixabay.com/photo/2015/12/01/20/28/green-1072828_960_720.jpg","13": "https://www.alwareness.org/wp-content/uploads/2018/10/Bomen-Bos.jpg", "13": "https://www.campz.be/info/wp-content/uploads/header-pic-mountain.jpeg", "14": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSUzRyiSPfzeIogLgkY1P8ugrvzls23SMhOcJi7vmUfCe4r1nKa", "14": "https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg", "15": "https://farm6.staticflickr.com/5720/22076039308_4e2fc21c5f_o.jpg" }
    };
  },
  methods: {
    reportError(event) {
      console.log(`${event.name}: ${event.message}`);
    }
  }
};
</script>
<style>
.transparant-banner {
  color: white;
}
</style>

在 Chrome 浏览器上,我在一些图像上出现错误。参见:

在 Firefox 上,一切都按预期工作。 Quasar relies 在其 javascript image() 上的 q-img 组件中,其 onerror 显然已被触发。

我的问题:

  1. 为什么会触发错误,因为它们看起来是随机的,而且由于图像 是否显示下载成功(出现错误后)?
  2. 我该如何解决这个问题?

This jsfiddle 展示行为,相关代码在components/Example.vue.

编辑: 错误消息是:EncodingError - The source image cannot be decoded.

Apparently .decode() causes the error。但具体原因是什么? 这个article describes .decode() and it indeed only applies to Chrome. In Quasar the decode is dealt with here.

Image.decode是异步浏览器api,它应该避免主线程在解码和绘制时被阻塞的情况。

这些图像用 src 初始化后会发生什么?浏览器开始下载它们。解码给你一个承诺,让你知道什么时候可以安全地将它插入 DOM.

但是,当您按顺序处理一些巨大的图像时(例如在示例中,每个大约 4mb),它有时会损坏。不知道为什么,但大小和数量很重要。

我用简单的代码玩过你的图像数组,比如

imagesArray.forEach(function(img) {
  var i = new Image();
  i.src = img;
  i.decode().then(function() {
    console.log("decoded");
  }).catch(function() {
    console.log("error");
  });
});

超过 5-6 张图片很容易出错。我建议尝试使用静态图像(图像 Content-type)。

无论如何,Quazar 使用 this.__updateSrc(); 将 src 值传递给 backgroundImage。这就是为什么即使是错误情况也会加载背景的原因。它使浏览器下载这些图像两次!在错误情况下,不使用使用解码的图像的第一次下载。

如果你想把这个错误记下来,注释掉__onError里面的this.hasError = true行。 属性 当 true 触发 Vue 为模板插槽抛出错误。

顺便说一句,在Quasar v1.0.0-rc.1 版本中,这个问题是solved,即它会下载没有错误状态。

你会注意到,使用 DevTools 网络,vue 下载的图像(后面的批次)是暂存的,一次下载不超过 6 个。同时打开连接的 HTTP common-sense 限制为 2。您还会注意到类星体加载的图像不遵循此规则:它们都是 (12) 并行下载的。在 Firefox 中,它们一次都被强制限制为 2 个。我假设发生的事情(唯一的证据是相同的图像以不同的字节大小下载,如果你注意到的话)是远程服务器 in-flight 重置了大量并行类星体连接(因为 header 仍然是 200).