代码之家  ›  专栏  ›  技术社区  ›  espresso_coffee

如何检查图像是否存在?

  •  2
  • espresso_coffee  · 技术社区  · 7 年前

    我有一个应用程序,其中图像应设置在一些页面。这些映像位于服务器上,每个映像都附加了唯一的ID。以下是图像名称的示例:

    AA_image1.jpg
    AB_image1.jpg
    AC_image1.jpg
    AD_image1.jpg
    AE_image1.jpg
    

    var images = [{
        "id": "AA",
        "image": "AA_image1.jpg"
      },
      {
        "id": "AB",
        "image": "AB_image1.jpg"
      },
      {
        "id": "AC",
        "image": "AC_image1.jpg"
      },
      {
        "id": "AD",
        "image": "AD_image1.jpg"
      },
      {
        "id": "AE",
        "image": "AE_image1.jpg"
      }
    ];
    
    var imgID = "AC";
    var imgPrimary = "AC_image1.jpg";
    var found = false;
    var imgDefault = "default.jpg";
    
    for (i = 1; i < images.length; i++) {
      if (images[i].id == imgID && (images[i].image).toLowerCase() == (imgID + '_image1.jpg').toLowerCase()) {
        found = true;
        break;
      }
    }
    
    if (found === true) {
      console.log(imgPrimary);
    } else {
      console.log(imgDefault);
    }

    上面的例子看起来很简单,但我关心的是,如果图像从文件夹中删除,JSON文件没有更新怎么办?在这种情况下,我们将加载不存在的图像,而不是默认图像。我想知道这种方法是否更好:

    var imgID = "AC";
    var imgNames = [imgID + '_image1','default'];
    var imgResults = {};
    
    for(var i = 0;  i < imgNames.length; i++){
       checkImage( imgNames[i] );
    }
    
    function checkImage( imgName, keyName ) {
        $.ajax({
            type: "GET",
            async: true,
            url: "images/"+imgName+".jpg",
        }).done(function(message,text,jqXHR){
             imgResults[imgName] = true;
        }).fail(function(jqXHR, textStatus, errorThrown){
             imgResults[imgName] = false;
        });
     }
    

    下面是一个例子 imgResults

    console.log(imgResults);
    

    {
      "default": true,
      "AG_image1": false
    }
    

    console.log(imgResults["AG_image1"]);
    

    这是控制台中的结果:

    undefined
    

    在这两者之间,我不确定哪一个更好、更安全。如果有人有什么建议,请告诉我。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Teemu    7 年前

    这可能是处理JS中丢失图像的最短代码。 imagePad 是对要在其中显示图像的DOM元素的引用。

    var img = new Image();
    img.addEventListener('error', function (e) {
        // Image not found, show the default
        this.src = iconBase + 'gen.png';
    });
    img.addEventListener('load', function () {
        imagePad.appendChild(img);
    }
    img.src = 'the_given_src';
    
        2
  •  1
  •   Community Mohan Dere    5 年前

    无法搜索的原因 imgResults 对象,这是因为AJAX请求是异步的,并且在尝试访问结果时请求尚未完成。您需要等待请求完成后才能继续。

    原因是 console.log console.log 是惰性的,在dev tools中展开对象之前不会对其求值, console.dir 此时将显示一个空对象。

    Promise.all 在对结果进行操作之前,等待所有承诺完成。

    验证资源是否存在

    HEAD 请求而不是 GET 请求,例如防止无故加载整个图像。由于XMLHttpRequest在当今时代得到了很好的支持,所以AJAX请求也不需要依赖于像jQuery这样的大型库。

    class ResourceValidator extends EventTarget {
      constructor(target) {
        super()
        this.target = target
        this._ready = false
        this._valid = false
        this.validate()
      }
      validate() {
        const request = new XMLHttpRequest()
        request.addEventListener('load', event => {
            this._ready = true
            this._valid = true
            this.dispatchEvent(new Event('ready'))
        })
        request.addEventListener('error', event => {
            this._ready = true
            this.dispatchEvent(new Event('ready'))
        })
        request.open('HEAD', this.target)
        request.send()
      }
      get ready() {
        return new Promise(resolve => {
          if(this._ready === true) resolve(true)
          else this.addEventListener('ready', _ => resolve(true))
        })
      }
      get valid() {
        return new Promise(resolve => {
          if(this._ready === true) resolve(this._valid)
          else this.addEventListener('ready', _ => resolve(this._valid))
        })
      }
    }
    
    async function validateImageSources(sources) {
      const results = {}
      const promises = []
    
      for(let source of sources) {
         const validator = new ResourceValidator(source)
         const promise = validator.valid
         promise.then(valid => results[source] = valid)
         promises.push(promise)
      }
      
      await Promise.all(promises)
      
      return results
    }
    
    validateImageSources([
      'https://picsum.photos/200',
      'https://nosuchaddress.io/image.png'
    ]).then(results => {
      console.log(results)
      console.log(results['https://picsum.photos/200'])
    })