Verificare se l'immagine esiste sul server utilizzando JavaScript?


124

Usando javascript c'è un modo per sapere se una risorsa è disponibile sul server? Per esempio ho immagini 1.jpg - 5.jpg caricate nella pagina html. Vorrei chiamare una funzione JavaScript ogni minuto circa che farebbe più o meno il seguente codice scratch ...

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

Pensieri? Grazie!

Risposte:


208

Potresti usare qualcosa come:

function imageExists(image_url){

    var http = new XMLHttpRequest();

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

    return http.status != 404;

}

Ovviamente potresti usare jQuery / similar per eseguire la tua richiesta HTTP.

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

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

    })

4
Ma il nome della funzione non dovrebbe essere fileExists perché funziona su .js .css .html o qualsiasi altro file disponibile pubblicamente.
CdR

1
La funzione è fantastica. L'ho messo nella mia raccolta :) Ho pensato che fileExistssarebbe stato un nome migliore perché questa funzione non controlla se l'immagine esiste sul server. Controlla se il file è accessibile dal server. Non è possibile verificare se quel file è effettivamente un'immagine. Potrebbe essere .pdf, .html, un file casuale rinominato in * .jpg o * .png. Se qualcosa finisce con .jpg non significa che sia immagine al 100% :)
CoR

9
Questo fallirà a meno che l'accesso alla risorsa non sia consentito dalle regole CORS. L'uso di un Imageoggetto non subisce questa limitazione. L'unico vantaggio di questo è che non scaricherà effettivamente l'immagine.
Alnitak

8
problema interdominio.
Amit Kumar

2
Questo funziona, ma tieni presente che richiede più tempo per elaborare la richiesta e non è la soluzione migliore. Inoltre non funziona su cross origin (sicuramente in chrome) quindi non puoi usarlo sul protocollo file: /// che significa nessun utilizzo locale.
Cameron

118

È possibile utilizzare il modo in cui funzionano i preloader di immagini per verificare se un'immagine esiste.

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

checkImage("foo.gif", function(){ alert("good"); }, function(){ alert("bad"); } );

JSFiddle


Ehi, bella funzione! Come nota a margine, questo è un modo interessante per restituire i risultati, direttamente in una funzione anonima. Normalmente lo farei con returnun'affermazione come @ajtrichards ha nella prima parte della sua risposta.
Sablefoste

Assolutamente; ma non ho mai veramente pensato al contrario di essere sincrono. Vengo da una lunga storia di codifica procedurale, ea volte mi manca il modo "altro" di vedere le cose ... Scommetto che non sono l'unico. ;-)
Sablefoste

2
Per i futuri googler che hanno problemi con questa soluzione, prova a spostare la definizione img.src subito dopo la nuova riga dell'immagine.
Gavin

52

Puoi semplicemente controllare se l'immagine viene caricata o meno utilizzando gli eventi incorporati forniti per tutte le immagini.

Gli eventi onloade onerrorti diranno se l'immagine è stata caricata correttamente o se si è verificato un errore:

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 = '/error.png';

    document.body.appendChild(err);
}

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

2
La migliore risposta per me, poiché funziona in ogni caso (problema di connessione, server esterno ...) +1
Reign.85

2
Confronta le prestazioni di questa risposta con l'alternativa AJAX.get. Questa risposta funziona molto più velocemente!
Samuel,

Questa soluzione mi piace, comunque presenta eventi in entrambi i casi (esecuzione asincrona), che possono causare problemi in alcune situazioni: suggerirei comunque di accodare l'immagine per poi sostituirla solo in caso di errori.
Giorgio Tempesta

@adeno, funziona quando il codice di stato: 404 non trovato
MahiMan

@Mahi - Il codice di stato non dovrebbe avere importanza, fintanto che la pagina 404 non restituisce effettivamente un'immagine valida, fallirà e attiverà il errorgestore.
adeneo

15

Se qualcuno arriva su questa pagina cercando di farlo in un client basato su React , puoi fare qualcosa come il seguente, che era una risposta originale fornita da Sophia Alpert del team React qui

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} />;
    );
}

7

Un approccio migliore e moderno consiste nell'utilizzare l' API Fetch ES6 per verificare se un'immagine esiste o meno:

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));

Assicurati di eseguire le richieste della stessa origine o che CORS sia abilitato sul server.


6

Se crei un tag immagine e lo aggiungi al DOM, dovrebbe attivarsi il suo evento onload o onerror. Se si attiva onerror, l'immagine non esiste sul server.


3

È possibile chiamare questa funzione JS per verificare se il file esiste sul server:

function doesFileExist(urlToFile)
{
    var xhr = new XMLHttpRequest();
    xhr.open('HEAD', urlToFile, false);
    xhr.send();

    if (xhr.status == "404") {
        console.log("File doesn't exist");
        return false;
    } else {
        console.log("File exists");
        return true;
    }
}

1
Buon sforzo. ma richiede un po 'di tempo quando si caricano più immagini in un unico modulo.
Nuwan Withanage

mostra un errore in xhr.send () se l'URL non esiste.
Avinash Sharma

3

Fondamentalmente una versione promessa di @espascarello e @adeneo risponde, con un parametro di fallback:

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)

// It can be also implemented using the async / await API.

Nota: personalmente potrei apprezzare di più la fetchsoluzione, ma ha uno svantaggio: se il tuo server è configurato in un modo specifico, può restituire 200/304, anche se il tuo file non esiste. Questo, d'altra parte, farà il lavoro.


2
Per fetch, puoi utilizzare la okproprietà responsedell'oggetto per verificare se la richiesta è fetch(url).then(res => {if(res.ok){ /*exist*/} else {/*not exist*/}});
andata a

Questo purtroppo non funziona per me se voglio controllare un'immagine di sfondo valida. background-image: url('/a/broken/url')mi dà 200e ok(Chrome 74).
HynekS

2

Puoi farlo con i tuoi assios impostando il percorso relativo alla cartella delle immagini corrispondente. L'ho fatto per ottenere un file json. Puoi provare lo stesso metodo per un file immagine, puoi fare riferimento a questi esempi

Se hai già impostato un'istanza axios con baseurl come server in un dominio diverso, dovrai utilizzare il percorso completo del file server statico in cui distribuisci l'applicazione web.

  axios.get('http://localhost:3000/assets/samplepic.png').then((response) => {
            console.log(response)
        }).catch((error) => {
            console.log(error)
        })

Se l'immagine viene trovata la risposta sarà 200 e in caso contrario sarà 404.

Inoltre, se il file immagine è presente nella cartella delle risorse all'interno di src, puoi eseguire una richiesta, ottenere il percorso ed eseguire la chiamata precedente con quel percorso.

var SampleImagePath = require('./assets/samplepic.png');
axios.get(SampleImagePath).then(...)

0

Funziona bene:

function checkImage(imageSrc) {
    var img = new Image();        
    try {
        img.src = imageSrc;
        return true;
    } catch(err) {
        return false;
    }    
}

12
Sei abbastanza sicuro che questo ritorni vero ogni volta?
Brandon McAlees

-3

È possibile fare riferimento a questo collegamento per verificare se esiste un file immagine con JavaScript.

checkImageExist.js:

    var image = new Image();
    var url_image = './ImageFolder/' + variable + '.jpg';
    image.src = url_image;
    if (image.width == 0) {
       return `<img src='./ImageFolder/defaultImage.jpg'>`;
    } else {
       return `<img src='./ImageFolder/`+variable+`.jpg'`;
    } } ```

1
L'ho appena provato. Non funziona . Restituisce sempre l'immagine predefinita. (Probabilmente perché il browser non ha tempo per effettuare la richiesta HTTP e caricare l'immagine prima di provare a testarne la larghezza).
Quentin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.