Periksa apakah gambar ada di server menggunakan JavaScript?

124

Menggunakan javascript, apakah ada cara untuk mengetahui apakah sumber daya tersedia di server? Misalnya saya memiliki gambar 1.jpg - 5.jpg yang dimuat ke halaman html. Saya ingin memanggil fungsi JavaScript setiap menit atau lebih yang kira-kira akan melakukan kode awal berikut ...

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

Pikiran? Terima kasih!

0xhughes
sumber

Jawaban:

208

Anda bisa menggunakan sesuatu seperti:

function imageExists(image_url){

    var http = new XMLHttpRequest();

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

    return http.status != 404;

}

Jelas Anda bisa menggunakan jQuery / serupa untuk melakukan permintaan HTTP Anda.

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

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

    })
ajtrichards
sumber
4
Tetapi seharusnya tidak berfungsi nama fileExists karena ini berfungsi pada .js .css .html atau file lain yang tersedia untuk umum.
CoR
1
Fungsinya luar biasa. Saya memasukkannya ke dalam koleksi saya :) Saya pikir fileExistsakan lebih baik nama karena fungsi ini tidak memeriksa apakah gambar ada di server. Ini memeriksa apakah file dapat diakses dari server. Tidak ada pemeriksaan apakah file itu benar-benar gambar. Bisa jadi .pdf, .html, beberapa file acak diubah namanya menjadi * .jpg atau * .png. Jika sesuatu diakhiri dengan .jpg itu tidak berarti itu 100% gambar :)
CoR
9
Ini akan gagal kecuali jika mengakses sumber daya diizinkan menurut aturan CORS. Menggunakan suatu Imageobjek tidak mengalami batasan itu. Satu-satunya keuntungan dari ini adalah tidak benar-benar mengunduh gambar.
Alnitak
8
masalah lintas domain.
Amit Kumar
2
Ini memang berfungsi, tetapi perlu diingat bahwa dibutuhkan waktu lebih lama untuk memproses permintaan dan bukanlah solusi terbaik. Juga tidak berfungsi pada cross origin (pasti di chrome) sehingga Anda tidak dapat menggunakannya pada file: /// protocol yang berarti tidak ada penggunaan lokal.
Cameron
118

Anda dapat menggunakan cara kerja prapemuat gambar dasar untuk menguji apakah gambar ada.

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.dll
sumber
Hei, fungsi keren! Sebagai catatan tambahan, ini adalah cara yang menarik untuk mengembalikan hasil, langsung ke fungsi anonim. Saya biasanya melakukan ini dengan returnpernyataan seperti yang dimiliki @ajtrichards di bagian pertama jawabannya.
Sablefoste
Benar; tetapi saya tidak pernah benar-benar memikirkan tentang cara lain untuk menjadi sinkron. Saya berasal dari sejarah panjang coding prosedural, dan terkadang melewatkan cara "lain" dalam memandang sesuatu ... Saya berani bertaruh saya bukan satu-satunya. ;-)
Sablefoste
2
Untuk calon karyawan Google yang mengalami masalah solusi ini, coba pindahkan definisi img.src ke segera setelah baris Gambar baru.
Gavin
52

Anda dapat memeriksa apakah gambar dimuat atau tidak dengan menggunakan peristiwa bawaan yang disediakan untuk semua gambar.

Acara onloaddan onerrorakan memberi tahu Anda jika gambar berhasil dimuat atau jika terjadi kesalahan:

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
sumber
2
Jawaban terbaik untuk saya, karena berfungsi dalam setiap kasus (masalah koneksi, server eksternal ...) +1
Berkuasa.85
2
Bandingkan kinerja jawaban ini dengan alternatif AJAX.get. Jawaban ini bekerja lebih cepat!
Samuel
Saya suka solusi ini, bagaimanapun itu memperkenalkan peristiwa dalam kedua kasus (eksekusi asinkron), yang dapat menyebabkan masalah dalam beberapa situasi: Saya akan menyarankan untuk menambahkan gambar dalam kasus apa pun dan kemudian menggantinya hanya jika terjadi kesalahan.
Giorgio Tempesta
@adeno, Apakah ini berfungsi ketika Kode Status: 404 Tidak Ditemukan
MahiMan
@Mahi - Kode status seharusnya tidak menjadi masalah, selama halaman 404 tidak benar-benar mengembalikan gambar yang valid, itu akan gagal dan memicu errorpenangan.
adeneo
15

Jika ada yang datang ke halaman ini ingin melakukan ini pada klien berbasis React , Anda dapat melakukan sesuatu seperti di bawah ini, yang merupakan jawaban asli yang diberikan oleh Sophia Alpert dari tim React di sini

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
sumber
7

Pendekatan yang lebih baik dan modern adalah menggunakan ES6 Fetch API untuk memeriksa apakah gambar ada atau tidak:

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

Pastikan Anda membuat permintaan yang sama-asal atau CORS diaktifkan di server.

attacomsian
sumber
6

Jika Anda membuat tag gambar dan menambahkannya ke DOM, baik peristiwa onload atau onerror harus diaktifkan. Jika onerror diaktifkan, gambar tidak ada di server.

Douglas
sumber
3

Anda dapat memanggil fungsi JS ini untuk memeriksa apakah file ada di 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;
    }
}
Ani Menon
sumber
1
Usaha yang bagus. tetapi memakan sedikit waktu saat memuat banyak gambar dalam satu bentuk.
Nuwan Withanage
itu menunjukkan kesalahan di xhr.send () jika url tidak ada.
Avinash Sharma
3

Pada dasarnya sebuah promisified versi @espascarello dan jawaban @adeneo, dengan parameter 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.

Catatan: Saya pribadi mungkin lebih menyukai fetchsolusinya, tetapi memiliki kekurangan - jika server Anda dikonfigurasi dengan cara tertentu, ia dapat mengembalikan 200/304, bahkan jika file Anda tidak ada. Ini, di sisi lain, akan melakukan pekerjaan itu.

HynekS
sumber
2
Sebab fetch, Anda dapat menggunakan okproperti responseobjek untuk memeriksa apakah permintaan berhasil atau tidak: fetch(url).then(res => {if(res.ok){ /*exist*/} else {/*not exist*/}});
attacomsian
Sayangnya itu tidak berfungsi untuk saya jika saya ingin memeriksa gambar latar belakang yang valid. background-image: url('/a/broken/url')memberi saya 200dan ok(Chrome 74).
HynekS
2

Anda dapat melakukan ini dengan aksios Anda dengan mengatur jalur relatif ke folder gambar yang sesuai. Saya telah melakukan ini untuk mendapatkan file json. Anda dapat mencoba metode yang sama untuk file gambar, Anda dapat merujuk contoh ini

Jika Anda telah menyetel instance axios dengan baseurl sebagai server di domain yang berbeda, Anda harus menggunakan jalur lengkap server file statis tempat Anda menerapkan aplikasi web.

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

Jika gambar ditemukan maka respon akan menjadi 200 dan jika tidak, akan menjadi 404.

Selain itu, jika file gambar ada dalam folder assets di dalam src, Anda bisa melakukan Requirement, mendapatkan path dan melakukan panggilan di atas dengan path tersebut.

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

Ini berfungsi dengan baik:

function checkImage(imageSrc) {
    var img = new Image();        
    try {
        img.src = imageSrc;
        return true;
    } catch(err) {
        return false;
    }    
}
MAtkins
sumber
12
Cukup yakin ini selalu mengembalikan true?
Brandon McAlees
-3

Anda dapat merujuk tautan ini untuk memeriksa apakah file gambar ada dengan 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'`;
    } } ```
Atik Vhora
sumber
1
Saya baru saja menguji ini. Ini tidak berhasil . Itu selalu mengembalikan gambar default. (Mungkin karena tidak ada waktu bagi browser untuk membuat permintaan HTTP dan memuat gambar sebelum Anda mencoba menguji lebarnya).
Quentin