首页 > 解决方案 > javascript Image() 下载时触发​​错误,不清楚原因

问题描述

我正在使用带有此代码的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的组件依赖于其显然被触发的q-imgjavascript 。image()onerror

我的问题:

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

这个 jsfiddle显示了行为,相关代码在components/Example.vue.

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

显然 .decode() 导致错误。但具体原因是什么?这篇文章描述.decode()并且它确实只适用于 Chrome。在 Quasar 中,这里处理解码。

标签: javascriptimagegoogle-chromevue.jsquasar-framework

解决方案


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

当这些图像用 src 初始化时会发生什么?浏览器开始下载它们。Decode 为您提供了一个 Promise 以了解何时可以安全地将其插入 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 张图像很容易出错。我建议尝试使用静态图像(图像内容类型)。

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

如果您想消除此错误,请使用this.hasError = trueinside __onError注释掉该行。此属性在 true 时触发 Vue 为模板槽抛出错误。

顺便说一句,在Quasar v1.0.0-rc.1 版本中,这个问题得到了解决,即下载时不会出现错误状态。


推荐阅读