Sjekk om bilde finnes på serveren ved å bruke JavaScript?


Ved å bruke JavaScript, finnes det en måte å sjekke om en ressurs er tilgjengelig på serveren? For eksempel har jeg bilder 1.jpg - 5.jpg lastet inn på HTML-siden. Jeg ønsker å kalle en JavaScript-funksjon hvert minutt eller så som omtrent gjør følgende skissekode...

if "../imgs/6.jpg" exists:
    var nImg = document.createElement("img6");
    nImg.src = "../imgs/6.jpg";

Tanker? Takk!

Svar #1

Du kan bruke noe sånt som:

function imageExists(image_url){

    var http = new XMLHttpRequest();

    http.open('HEAD', image_url, false);
    http.send();

    return http.status != 404;

}

Selvfølgelig kan du bruke jQuery/lignende for å utføre HTTP-forespørselen din.

$.get(image_url)
    .done(function() { 
        // Do something now you know the image exists.

    }).fail(function() { 
        // Image doesn't exist - do something else.

    })

Svar #2

Du kan bruke den grunnleggende måten bildeforlastere fungerer på for å teste om et bilde eksisterer.

    function checkImage(imageSrc, good, bad) {
        var img = new Image();
        img.onload = good; 
        img.onerror = bad;
        img.src = imageSrc;
    }
    
    checkImage("foo.gif", function(){ console.log("good"); }, function(){ console.log("bad"); } );

    checkImage("favicon.ico", function(){ console.log("good"); }, function(){ console.log("bad"); } );

JSFiddle

Svar #3

Du kan bare sjekke om bildet lastes eller ikke ved å bruke de innebygde hendelsene som er tilgjengelige for alle bilder.

Hendelsene onload og onerror vil fortelle deg om bildet ble lastet inn riktig eller om en feil oppsto :

var image = new Image();

image.onload = function() {
    // image exists and is loaded
    document.body.appendChild(image);
}
image.onerror = function() {
    // image did not load

    var err = new Image();
    err.src = '/favicon.ico';

    document.body.appendChild(err);
}

image.src = "../imgs/6.jpg";

Svar #4

En bedre og moderne tilnærming er å bruke ES6 Fetch API for å sjekke om et bilde finnes eller ikke:

fetch('https://via.placeholder.com/150', { method: 'HEAD' })
    .then(res => {
        if (res.ok) {
            console.log('Image exists.');
        } else {
            console.log('Image does not exist.');
        }
    }).catch(err => console.log('Error:', err));

Sørg for at du enten gjør forespørsler til samme opprinnelse eller at CORS er aktivert på serveren.

Svar #5

Hvis noen kommer til denne siden for å gjøre dette i en React-basert klient, kan du gjøre noe som det nedenfor, som opprinnelig var et svar gitt av Sophia Alpert fra React-teamet her

getInitialState: function(event) {
    return {image: "http://example.com/primary_image.jpg"};
},
handleError: function(event) {
    this.setState({image: "http://example.com/failover_image.jpg"});
},
render: function() {
    return (
        <img onError={this.handleError} src={src} />;
    );
}

Svar #6

I utgangspunktet en promisified versjon av svarene til @espascarello og @adeneo, med en fallback-parameter:

const getImageOrFallback = (path, fallback) => {
  return new Promise(resolve => {
    const img = new Image();
    img.src = path;
    img.onload = () => resolve(path);
    img.onerror = () => resolve(fallback);
  });
};

// Usage:

const link = getImageOrFallback(
  'https://www.fillmurray.com/640/360',
  'https://via.placeholder.com/150'
  ).then(result => console.log(result) || result)

Rediger mars 2021 Etter en samtale med @hitautodestruct bestemte jeg meg for å legge til en mer "kanonisk" versjon av Promise-basert funksjon. onerror-tilfellet blir nå avvist, men deretter fanget og returnerer en standardverdi:

function getImageOrFallback(url, fallback) {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.src = url
    img.onload = () => resolve(url)
    img.onerror = () => {
      reject(`image not found for url ${url}`)
    }
  }).catch(() => {
    return fallback
  })
}

getImageOrFallback("https://google.com", "https://picsum.photos/400/300").then(validUrl => {
  console.log(validUrl)
  document.body.style.backgroundImage = `url(${validUrl})`
})
html, body {
  height: 100%;
  background-repeat: no-repeat;
  background-position: 50% 50%;
  overflow-y: hidden;
}

Merk: Jeg kan personlig like fetch-løsningen bedre, men den har en ulempe - hvis serveren din er konfigurert på en bestemt måte, kan den returnere 200/304, selv om filen ikke finnes. Dette, derimot, vil gjøre jobben.

Relaterte artikler