Перевірте, чи існує зображення на сервері за допомогою 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.