Перевірте, чи існує зображення на сервері за допомогою JavaScript?


124

Використовуючи javascript, чи є спосіб визначити, чи доступний ресурс на сервері? Наприклад, у мене на сторінці html завантажені зображення 1.jpg - 5.jpg. Я хотів би викликати функцію JavaScript щохвилини або близько того, що б приблизно виконати наступний код скретчу ...

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

Думки? Дякую!

Відповіді:


208

Ви можете використовувати щось на кшталт:

function imageExists(image_url){

    var http = new XMLHttpRequest();

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

    return http.status != 404;

}

Очевидно, ви можете використовувати jQuery / similar для виконання свого HTTP-запиту.

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

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

    })

4
Але не повинно функціонувати ім'я fileExists, оскільки це працює на .js .css .html або будь-який інший загальнодоступний файл.
КР

1
Функція приголомшлива. Я помістив його у свою колекцію :) Я подумав, fileExistsщо краще назвати, оскільки ця функція не перевіряє, чи існує зображення на сервері. Він перевіряє, чи доступний файл із сервера. Немає перевірки, чи справді цей файл є зображенням. Це може бути .pdf, .html, якийсь випадковий файл, перейменований на * .jpg або * .png. Якщо щось закінчується .jpg, це не означає, що це 100% зображення :)
CoR

9
Це не вдасться, якщо доступ до ресурсу не дозволений за правилами CORS. Використання Imageоб'єкта не зазнає цього обмеження. Єдиною перевагою цього є те, що він фактично не завантажує зображення.
Альнітак

8
питання міждоменного домену
Аміт Кумар

2
Це працює, але майте на увазі, що обробка запиту займає більше часу, і це не найкраще рішення. Крім того, він не працює з поперечним походженням (безумовно, у хромі), тому ви не можете використовувати його у файлі: /// протокол, що означає відсутність локального використання.
Камерон

118

Ви можете використовувати основний спосіб роботи завантажувачів зображень, щоб перевірити, чи існує зображення.

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


Гей, класна функція! Як зауваження, це цікавий спосіб повернення результатів, безпосередньо в анонімну функцію. Як правило, я б це робив із returnзаявою, на зразок @ajtrichards у першій частині своєї відповіді.
Sablefoste

Абсолютно; але я ніколи насправді не думав про те, щоб інший спосіб був синхронним. Я виходжу з багаторічної історії процедурного кодування, а іноді пропускаю "інший" погляд на речі ... Б'юсь об заклад, я не єдиний. ;-)
Sablefoste

2
Для майбутніх googlers, які мають проблему з цим рішенням, спробуйте перенести визначення img.src безпосередньо після нової лінії Image.
Гавін

52

Ви можете просто перевірити, завантажується чи ні, використовуючи вбудовані події, які передбачені для всіх зображень.

Події onloadта onerrorподії підкажуть, чи вдало завантажено зображення чи сталася помилка:

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
Найкраща відповідь для мене, оскільки вона працює в кожному випадку (проблема з підключенням, зовнішній сервер ...) +1
Reign.85

2
Порівнював ефективність цієї відповіді з альтернативою AJAX.get. Ця відповідь виконує набагато швидше!
Самуїл

Мені подобається це рішення, так як воно вводить події в обох випадках (асинхронне виконання), що може спричинити проблеми в деяких ситуаціях: я б запропонував додати зображення в будь-якому випадку, а потім замінити його лише у випадку помилок.
Джорджіо Темпеста

@adeno, чи працює, коли код статусу: 404 не знайдено
MahiMan

@Mahi - Код статусу не повинен мати значення, доки сторінка 404 насправді не поверне дійсне зображення, воно вийде з ладу і запустить errorобробник.
аденео

15

Якщо хтось заходить на цю сторінку, бажаючи зробити це у клієнта, що базується на React , ви можете зробити щось на кшталт наведеного нижче, яке було оригінальною відповіддю, яку надала Софія Альперт із команди React тут

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

Кращим і сучасним підходом є використання ES6 Fetch API для перевірки наявності зображення чи ні:

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

Переконайтеся, що ви або робите запити одного походження або CORS увімкнено на сервері.


6

Якщо ви створите тег зображення та додасте його до DOM, його подія завантаження або onerror має спрацювати. Якщо onerror запускається, зображення не існує на сервері.


3

Ви можете зателефонувати на цю функцію JS, щоб перевірити, чи існує файл на сервері:

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
Гарна спроба. але небагато часу забирає при завантаженні декількох зображень в одній формі.
Nuwan Withanage

він показує помилку на xhr.send (), якщо URL-адреса не існує.
Avinash Sharma

3

В основному, це обіцяна версія відповідей @espascarello та @adeneo із запасним параметром:

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.

Примітка:fetch рішення особисто мені може сподобатися , але воно має недолік - якщо ваш сервер налаштований певним чином, він може повернути 200/304, навіть якщо ваш файл не існує. Це, з іншого боку, зробить цю роботу.


2
Тому що fetchви можете скористатися okвластивістю responseоб’єкта, щоб перевірити, чи був запит успішним чи ні: fetch(url).then(res => {if(res.ok){ /*exist*/} else {/*not exist*/}});
attachcomsian

Це, на жаль, не працює для мене, якщо я хочу перевірити дійсне фонове зображення. background-image: url('/a/broken/url')дає мені 200і ok(Chrome 74).
HynekS

2

Це можна зробити за допомогою аксіосів, встановивши відносний шлях до відповідної папки зображень. Я зробив це для отримання файлу json. Ви можете спробувати той же спосіб для файлу зображення, ви можете посилатися на ці приклади

Якщо ви вже встановили екземпляр axios з baseurl в якості сервера в іншому домені, вам доведеться використовувати повний шлях статичного файлового сервера, де ви розгортаєте веб-додаток.

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

Якщо зображення знайдено, відповідь буде 200, а якщо ні - 404.

Крім того, якщо файл зображення присутній у папці активів всередині src, ви можете зробити вимогу, отримати шлях і зробити вищезгаданий виклик за допомогою цього шляху.

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

0

Це добре працює:

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

12
Досить впевнений, що це щоразу повертається правдою?
Брендон МакАліс

-3

Ви можете посилатися на це посилання, щоб перевірити, чи існує файл зображення з 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
Я щойно це перевірив. Це не працює . Він завжди повертає зображення за замовчуванням. (Можливо, тому, що браузер не має часу робити HTTP-запит і завантажувати зображення, перш ніж спробувати перевірити його ширину).
Квентін,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.