Überprüfen Sie mithilfe von JavaScript, ob das Bild auf dem Server vorhanden ist.

124

Gibt es eine Möglichkeit, mithilfe von Javascript festzustellen, ob eine Ressource auf dem Server verfügbar ist? Zum Beispiel habe ich Bilder 1.jpg - 5.jpg in die HTML-Seite geladen. Ich möchte jede Minute eine JavaScript-Funktion aufrufen, die ungefähr den folgenden Scratch-Code ausführt ...

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

Gedanken? Vielen Dank!

0xhughes
quelle

Antworten:

207

Sie könnten etwas verwenden wie:

function imageExists(image_url){

    var http = new XMLHttpRequest();

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

    return http.status != 404;

}

Natürlich können Sie jQuery / Similar verwenden, um Ihre HTTP-Anforderung auszuführen.

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

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

    })
Ajtrichards
quelle
4
Der Funktionsname sollte jedoch nicht fileExists sein, da dies für .js .css .html oder eine andere öffentlich verfügbare Datei funktioniert.
AdR
1
Die Funktion ist fantastisch. Ich habe es in meine Sammlung aufgenommen :) Ich dachte, es fileExistswäre ein besserer Name, da diese Funktion nicht überprüft, ob das Bild auf dem Server vorhanden ist. Es wird geprüft, ob auf die Datei vom Server aus zugegriffen werden kann. Es wird nicht überprüft, ob es sich bei dieser Datei tatsächlich um ein Bild handelt. Es kann sich um .pdf, .html handeln, eine zufällige Datei, die in * .jpg oder * .png umbenannt wurde. Wenn etwas mit .jpg endet, heißt das nicht, dass es 100% Bild ist :)
AdR
9
Dies schlägt fehl, es sei denn, der Zugriff auf die Ressource ist gemäß den CORS-Regeln zulässig. Die Verwendung eines ImageObjekts unterliegt dieser Einschränkung nicht. Der einzige Vorteil davon ist, dass das Bild nicht heruntergeladen wird.
Alnitak
8
domänenübergreifendes Problem.
Amit Kumar
2
Dies funktioniert, aber denken Sie daran, dass die Bearbeitung der Anfrage länger dauert und nicht die beste Lösung ist. Außerdem funktioniert es nicht bei Cross-Origin (definitiv in Chrome), sodass Sie es nicht für das Protokoll file: /// verwenden können, was bedeutet, dass es nicht lokal verwendet wird.
Cameron
117

Sie können die grundlegende Funktionsweise von Bildvorladern verwenden, um zu testen, ob ein Bild vorhanden ist.

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

Epascarello
quelle
Hey, coole Funktion! Nebenbei bemerkt ist dies eine interessante Möglichkeit, die Ergebnisse direkt in eine anonyme Funktion zurückzugeben. Normalerweise würde ich dies mit einer returnAussage tun, wie sie @ajtrichards im ersten Teil seiner Antwort hat.
Sablefoste
Absolut; aber ich habe nie wirklich darüber nachgedacht, dass der andere Weg synchron ist. Ich komme aus einer langen Geschichte der prozeduralen Codierung und vermisse manchmal die "andere" Sichtweise der Dinge ... Ich wette, ich bin nicht der einzige. ;-)
Sablefoste
2
Versuchen Sie für zukünftige Googler, die ein Problem mit dieser Lösung haben, die img.src-Definition unmittelbar nach der neuen Bildzeile zu verschieben.
Gavin
52

Sie können einfach überprüfen, ob das Bild geladen wird oder nicht, indem Sie die integrierten Ereignisse verwenden, die für alle Bilder bereitgestellt werden.

Das onloadundonerror Veranstaltungen werden Ihnen sagen , ob das Bild erfolgreich geladen wurde oder ein Fehler ist aufgetreten:

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";
Adeneo
quelle
2
Die beste Antwort für mich, da es in jedem Fall funktioniert (Verbindungsproblem, externer Server ...) +1
Reign.85
2
Verglich die Leistung dieser Antwort mit der Alternative AJAX.get. Diese Antwort funktioniert viel schneller!
Samuel
Ich mag diese Lösung, trotzdem führt sie in beiden Fällen Ereignisse ein (asynchrone Ausführung), die in einigen Situationen zu Problemen führen können: Ich würde empfehlen, das Bild auf jeden Fall anzuhängen und es dann nur im Fehlerfall zu ersetzen.
Giorgio Tempesta
@adeno, funktioniert es, wenn Statuscode: 404 nicht gefunden
ManZ
@Mahi - Der Statuscode sollte keine Rolle spielen, solange die 404-Seite kein gültiges Bild zurückgibt, schlägt sie fehl und löst den errorHandler aus.
Adeneo
15

Wenn jemand auf diese Seite kommt, um dies in einem React- basierten Client zu tun , können Sie Folgendes tun: Dies war ein Antwort-Original, das Sophia Alpert vom React-Team hier bereitgestellt hat

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} />;
    );
}
Jordan Bonitatis
quelle
6

Wenn Sie ein Image-Tag erstellen und es dem DOM hinzufügen, sollte entweder das Onload- oder das Onerror-Ereignis ausgelöst werden. Wenn ein Fehler ausgelöst wird, ist das Image nicht auf dem Server vorhanden.

Douglas
quelle
6

Ein besserer und moderner Ansatz besteht darin, mithilfe der ES6- Abruf-API zu überprüfen, ob ein Bild vorhanden ist oder nicht:

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

Stellen Sie sicher, dass Sie entweder Anfragen mit demselben Ursprung stellen oder CORS auf dem Server aktiviert ist.

Attacomsian
quelle
3

Sie können diese JS-Funktion aufrufen, um zu überprüfen, ob eine Datei auf dem Server vorhanden ist:

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;
    }
}
Ani Menon
quelle
1
Guter Versuch. aber etwas zeitaufwändig, wenn mehrere Bilder in einem Formular geladen werden.
Nuwan Withanage
Bei xhr.send () wird ein Fehler angezeigt, wenn die URL nicht vorhanden ist.
Avinash Sharma
3

Grundsätzlich antwortet eine vielversprechende Version von @espascarello und @adeneo mit einem 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)

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

Hinweis: Ich persönlich mag die fetchLösung vielleicht mehr, aber sie hat einen Nachteil: Wenn Ihr Server auf eine bestimmte Weise konfiguriert ist, kann er 200/304 zurückgeben, auch wenn Ihre Datei nicht vorhanden ist. Dies wird andererseits die Arbeit erledigen.

HynekS
quelle
2
Für fetchSie die verwenden können okEigenschaft des responseObjekts zu überprüfen , ob die Anforderung erfolgreich war oder nicht: fetch(url).then(res => {if(res.ok){ /*exist*/} else {/*not exist*/}});
attacomsian
Das funktioniert bei mir leider nicht, wenn ich ein gültiges Hintergrundbild überprüfen möchte. background-image: url('/a/broken/url')gibt mir 200und ok(Chrome 74).
HynekS
2

Sie können dies mit Ihren Axios tun, indem Sie den relativen Pfad zum entsprechenden Bilderordner festlegen. Ich habe dies getan, um eine JSON-Datei zu erhalten. Sie können dieselbe Methode für eine Bilddatei ausprobieren. Sie können sich auf diese Beispiele beziehen

Wenn Sie bereits eine Axios-Instanz mit baseurl als Server in einer anderen Domäne festgelegt haben, müssen Sie den vollständigen Pfad des statischen Dateiservers verwenden, auf dem Sie die Webanwendung bereitstellen.

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

Wenn das Bild gefunden wird, lautet die Antwort 200 und wenn nicht, 404.

Wenn sich die Bilddatei im Assets-Ordner in src befindet, können Sie eine Anforderung ausführen, den Pfad abrufen und den obigen Aufruf mit diesem Pfad ausführen.

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

Das funktioniert gut:

function checkImage(imageSrc) {
    var img = new Image();        
    try {
        img.src = imageSrc;
        return true;
    } catch(err) {
        return false;
    }    
}
MAtkins
quelle
11
Ziemlich sicher, dass dies jedes Mal wahr ist?
Brandon McAlees
-3

Über diesen Link können Sie überprüfen, ob eine Bilddatei mit JavaScript vorhanden ist.

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'`;
    } } ```
Atik Vhora
quelle
1
Ich habe das gerade getestet. Es funktioniert nicht . Es wird immer das Standardbild zurückgegeben. (Wahrscheinlich, weil der Browser keine Zeit hat, die HTTP-Anforderung zu stellen und das Bild zu laden, bevor Sie versuchen, die Breite zu testen.)
Quentin