Vérifier si l'image existe sur le serveur en utilisant JavaScript?


124

Utiliser javascript est-il possible de savoir si une ressource est disponible sur le serveur? Par exemple, j'ai des images 1.jpg - 5.jpg chargées dans la page html. Je voudrais appeler une fonction JavaScript toutes les minutes environ qui ferait à peu près le code de travail suivant ...

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

Pensées? Merci!

Réponses:


208

Vous pouvez utiliser quelque chose comme:

function imageExists(image_url){

    var http = new XMLHttpRequest();

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

    return http.status != 404;

}

Évidemment, vous pouvez utiliser jQuery / similar pour effectuer votre requête HTTP.

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

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

    })

4
Mais le nom de la fonction ne devrait pas être fileExists car cela fonctionne sur .js .css .html ou tout autre fichier accessible au public.
CdR du

1
La fonction est géniale. Je l'ai mis dans ma collection :) Je pensais que ce fileExistsserait un meilleur nom car cette fonction ne vérifie pas si l'image existe sur le serveur. Il vérifie si le fichier est accessible depuis le serveur. Il n'y a pas de vérification si ce fichier est réellement une image. Cela peut être .pdf, .html, un fichier aléatoire renommé en * .jpg ou * .png. Si quelque chose se termine par .jpg, cela ne veut pas dire que c'est 100% image :)
CoR

9
Cela échouera à moins que l'accès à la ressource ne soit autorisé selon les règles CORS. L'utilisation d'un Imageobjet ne souffre pas de cette limitation. Le seul avantage de ceci est qu'il ne téléchargera pas réellement l'image.
Alnitak

8
problème interdomaine.
Amit Kumar

2
Cela fonctionne, mais gardez à l'esprit que le traitement de la demande prend plus de temps et n'est pas la meilleure solution. De plus, cela ne fonctionne pas sur l'origine croisée (certainement dans Chrome), vous ne pouvez donc pas l'utiliser sur le protocole file: ///, ce qui signifie aucune utilisation locale.
Cameron

118

Vous pouvez utiliser le fonctionnement de base des préchargeurs d'images pour tester si une image existe.

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


Hé, fonction cool! En passant, c'est une manière intéressante de renvoyer les résultats, directement dans une fonction anonyme. Je ferais normalement cela avec une returndéclaration comme @ajtrichards dans la première partie de sa réponse.
Sablefoste

Absolument; mais je n'ai jamais vraiment pensé que l'inverse était synchrone. Je viens d'une longue histoire de codage procédural, et je rate parfois «l'autre» façon de voir les choses ... Je parie que je ne suis pas la seule. ;-)
Sablefoste

2
Pour les futurs googleurs ayant un problème avec cette solution, essayez de déplacer la définition img.src immédiatement après la nouvelle ligne Image.
Gavin le

52

Vous pouvez simplement vérifier si l'image se charge ou non en utilisant les événements intégrés fournis pour toutes les images.

Les événements onloadet onerrorvous indiqueront si l'image a été chargée avec succès ou si une erreur s'est produite:

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 meilleure réponse pour moi, car cela fonctionne dans tous les cas (problème de connexion, serveur externe ...) +1
Reign.85

2
Comparé les performances de cette réponse avec l'alternative AJAX.get. Cette réponse est beaucoup plus rapide!
Samuel

J'aime cette solution, de toute façon elle introduit des événements dans les deux cas (exécution asynchrone), ce qui peut poser des problèmes dans certaines situations: je suggérerais de rajouter l'image dans tous les cas et de la remplacer uniquement en cas d'erreurs.
Giorgio Tempesta

@adeno, fonctionne-t-il lorsque le code d'état: 404 est introuvable
MahiMan

@Mahi - Le code d'état ne devrait pas avoir d'importance, tant que la page 404 ne renvoie pas réellement une image valide, elle échouera et déclenchera le errorgestionnaire.
adeneo

15

Si quelqu'un vient sur cette page pour le faire dans un client basé sur React , vous pouvez faire quelque chose comme ci-dessous, qui était une réponse originale fournie par Sophia Alpert de l'équipe React ici

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

Une approche meilleure et moderne consiste à utiliser l' API ES6 Fetch pour vérifier si une image existe ou non:

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

Assurez-vous que vous effectuez les demandes de même origine ou que CORS est activé sur le serveur.


6

Si vous créez une balise d'image et l'ajoutez au DOM, son événement onload ou onerror devrait se déclencher. Si une erreur se déclenche, l'image n'existe pas sur le serveur.


3

Vous pouvez appeler cette fonction JS pour vérifier si le fichier existe sur le serveur:

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
Bon effort. mais peu de temps lors du chargement de plusieurs images sous une seule forme.
Nuwan Withanage

il affiche une erreur à xhr.send () si l'url n'existe pas.
Avinash Sharma le

3

Fondamentalement, une version promis de @espascarello et @adeneo répond, avec un paramètre de repli:

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.

Remarque: Personnellement, j'apprécie fetchdavantage la solution, mais elle présente un inconvénient: si votre serveur est configuré d'une manière spécifique, il peut renvoyer 200/304, même si votre fichier n'existe pas. Ceci, d'autre part, fera le travail.


2
Pour fetch, vous pouvez utiliser la okpropriété de l' responseobjet pour vérifier si la requête a réussi ou non: fetch(url).then(res => {if(res.ok){ /*exist*/} else {/*not exist*/}});
attacomsian

Cela ne fonctionne malheureusement pas pour moi si je veux vérifier une image de fond valide. background-image: url('/a/broken/url')me donne 200et ok(Chrome 74).
HynekS

2

Vous pouvez le faire avec votre axios en définissant un chemin relatif vers le dossier d'images correspondant. J'ai fait cela pour obtenir un fichier json. Vous pouvez essayer la même méthode pour un fichier image, vous pouvez vous référer à ces exemples

Si vous avez déjà défini une instance axios avec baseurl comme serveur dans un domaine différent, vous devrez utiliser le chemin complet du serveur de fichiers statiques sur lequel vous déployez l'application Web.

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

Si l'image est trouvée, la réponse sera 200 et sinon, elle sera 404.

De plus, si le fichier image est présent dans le dossier assets à l'intérieur de src, vous pouvez faire un require, obtenir le chemin et faire l'appel ci-dessus avec ce chemin.

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

0

Cela fonctionne bien:

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

12
Assez sûr que cela revient vrai à chaque fois?
Brandon McAlees

-3

Vous pouvez consulter ce lien pour vérifier si un fichier image existe avec 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
Je viens de tester ça. Ça ne marche pas . Il renvoie toujours l'image par défaut. (Probablement parce que le navigateur n'a pas le temps de faire la requête HTTP et de charger l'image avant d'essayer d'en tester la largeur).
Quentin
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.