Проверить, существует ли изображение на сервере с помощью JavaScript?


124

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

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

Мысли? Спасибо!

Ответы:


209

Вы можете использовать что-то вроде:

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 или любым другим общедоступным файлом.
— CoR

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

9
Это не удастся, если доступ к ресурсу не разрешен правилами CORS. Использование Imageобъекта не страдает этим ограничением. Единственное преимущество этого заключается в том, что на самом деле он не загружает изображение.
— Alnitak

8
междоменная проблема.
— Амит Кумар,

2
Это работает, но имейте в виду, что обработка запроса занимает больше времени и не является лучшим решением. Также он не работает с перекрестным происхождением (определенно в хроме), поэтому вы не можете использовать его по протоколу file: ///, что означает отсутствие локального использования.
— Кэмерон

119

Вы можете использовать основной способ работы предварительных загрузчиков изображений, чтобы проверить, существует ли изображение.

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
Если у будущих гуглеров возникнут проблемы с этим решением, попробуйте переместить определение img.src сразу после новой строки изображения.
— Gavin

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
Лучший ответ для меня, так как он работает во всех случаях (проблема с
— подключением

2
Сравнил производительность этого ответа с альтернативой AJAX.get. Этот ответ выполняется намного быстрее!
— Samuel

Мне нравится это решение, так или иначе, оно вводит события в обоих случаях (асинхронное выполнение), что может вызвать проблемы в некоторых ситуациях: я бы предложил добавить изображение в любом случае, а затем заменить его только в случае ошибок.
— Джорджио Темпеста

@adeno, это работает, когда код состояния: 404 не найден
— MahiMan

@Mahi - код состояния не имеет значения, пока страница 404 не возвращает действительное изображение, она завершится ошибкой и вызовет errorобработчик.
— adeneo

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, должно срабатывать событие onload или 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-адрес не существует.
— Авинаш Шарма

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*/}});
— attacomsian

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

2

Вы можете сделать это с помощью своих axios, установив относительный путь к соответствующей папке изображений. Я сделал это для получения файла 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
Уверены, что это каждый раз возвращает истину?
— Brandon McAlees

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