Невозможно загрузить изображение в HTML [дубликат]

Лучший способ объяснить эту простую тему - дать простой пример и ссылку ссылки: -

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

Html:

<form id="Demo">
<input type="radio" name="Gender" value="Male" /> Male <br />
<input type="radio" name="Gender" value="Female" /> Female<br />
<input type="radio" name="Gender" value="others" /> others <br />
</form>

jquery: -

 $(document).ready(function(){
        $('#Demo input').on('change', function() {
            alert($('input[name="Gender"]:checked', '#Demo').val());
        });
    });
484
задан Peter Mortensen 15 May 2016 в 19:54
поделиться

24 ответа

Обработать событие onError, чтобы изображение переназначало его источник с помощью JavaScript:

function imgError(image) {
    image.onerror = "";
    image.src = "/images/noimage.gif";
    return true;
}
<img src="image.png" onerror="imgError(this);"/>

Или без функции JavaScript:

<img src="image.png" onError="this.onerror=null;this.src='/images/noimage.gif';" />

Следующие В таблице совместимости перечислены браузеры, поддерживающие средство ошибки:

http://www.quirksmode.org/dom/events/error.html

663
ответ дан Ry- 16 August 2018 в 14:30
поделиться
  • 1
    Вероятно, вы хотите очистить параметр onerror before src. В противном случае, если noimage.gif также отсутствует, вы можете завершить «переполнение стека». – pcorcoran 18 September 2008 в 18:14
  • 2
    Я подумал & amp; надеялись, что мы отходим от встроенных атрибутов для событий javascript ... – redsquare 2 September 2009 в 07:04
  • 3
    redsquare ... они совершенно понятны, когда вы разумны в том, чтобы держать их под контролем и даже быть полезными, когда хотите, чтобы ваша разметка отражала то, что на самом деле произойдет. – Nicole 18 February 2010 в 22:41
  • 4
    Хорошая точка NickC, о разметке, показывающей, что происходит, я просто сжимаю, когда смотрю на нее: P – SSH This 27 March 2012 в 22:11
  • 5
    @redsquare, я полностью согласен, но это уникальный случай. Inline - это единственное место, где вы можете прикрепить слушателя с абсолютной уверенностью в том, что событие не будет срабатывать до того, как ваш слушатель будет подключен. Если вы сделаете это в конце документа или дождитесь загрузки DOM, вы можете пропустить событие ошибки на некоторых изображениях. Вам нехорошо приложить обработчик ошибок после того, как событие было запущено. – Prestaul 5 September 2012 в 01:40

В случае, если кто-то вроде меня, пытается присоединить событие error к динамическому тегу HTML img, я хотел бы указать, что есть catch:

По-видимому img ошибки не вызывают пузырь в большинстве браузеров, вопреки тому, что говорит стандарт .

Итак, что-то вроде следующего не будет работать:

$(document).on('error', 'img', function () { ... })

Надеюсь, это будет полезно кому-то другому. Хотелось бы, чтобы я видел это здесь в этой теме. Но я этого не сделал. Итак, я добавляю его

110
ответ дан 9KSoft 16 August 2018 в 14:30
поделиться
  • 1
    здесь, спасибо, за то, что указали, что – BeNdErR 27 January 2014 в 16:26
  • 2
    не работает. Я загружаю мертвое изображение динамически и присоединяю его к dom, и событие 'error' не запускается. – vsync 14 June 2014 в 20:51
  • 3
    черт возьми, я не заметил, что это пример того, как это не делать. – Benjamin 11 August 2015 в 17:09

Это JavaScript, должен быть совместим с перекрестным браузером и поставляет без уродливой разметки onerror="":

var sPathToDefaultImg = 'http://cdn.sstatic.net/stackexchange/img/logos/so/so-icon.png',
    validateImage = function( domImg ) {
        oImg = new Image();
        oImg.onerror = function() {
            domImg.src = sPathToDefaultImg;
        };
        oImg.src = domImg.src;
    },
    aImg = document.getElementsByTagName( 'IMG' ),
    i = aImg.length;

while ( i-- ) {
    validateImage( aImg[i] );
}

CODEPEN:

5
ответ дан Axel 16 August 2018 в 14:30
поделиться

Вы можете использовать собственную выборку GitHub для этого:

Frontend: https://github.com/github/fetch или для Backend, версия Node.js: https://github.com/bitinn/node-fetch

fetch(url)
  .then(function(res) {
    if (res.status == '200') {
      return image;
    } else {
      return placeholder;
    }
  }

Изменить: этот метод заменит XHR и предположительно уже был в Chrome. Для тех, кто читает это в будущем, вам может не понадобиться упомянутая выше библиотека.

5
ответ дан BarryMode 16 August 2018 в 14:30
поделиться

Если изображение не может быть загружено (например, поскольку оно отсутствует в указанном URL-адресе), URL-адрес изображения будет изменен на значение по умолчанию,

Подробнее о .error ()

$('img').on('error', function (e) {
  $(this).attr('src', 'broken.png');
});

1
ответ дан CasperSL 16 August 2018 в 14:30
поделиться

Я использую приведенный ниже код, который сначала пытается найти аватар текущего пользователя на основе их идентификатора пользователя, который в этом случае равен «123», и если он не находит изображение аватара, код onerror изменяет img src на placeholder изображение.

<img src="avatars/users/123.png" onerror="this.src='/ngTribeBase/src/assets/img/avatars/male.png'" />
-4
ответ дан Charles Naccio 16 August 2018 в 14:30
поделиться
  • 1
    это решение не только уже является частью принятого ответа (более старого), но и не имеет ключевого this.onerror=null;, который предотвращает бесконечный цикл, если ваш альт-образ также будет нарушен. – RozzA 22 November 2015 в 06:19
  • 2
    Я просто делился своим опытом, и он отлично работал для меня без каких-либо бесконечных циклов. – Charles Naccio 15 December 2017 в 16:57
  • 3
    Я просто объяснял свой downvote, поставил плохой url для изображения и amp; image image & amp; посмотреть, что происходит – RozzA 29 January 2018 в 04:08

Я нашел этот пост, глядя на эту другую SO-почту . Ниже приведен экземпляр ответа, который я дал там.

Я знаю, что это старый поток, но React стал популярным, и, возможно, кто-то, кто использует React, придет сюда искать ответ на ту же проблему.

Итак, если вы используете 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} />;
    );
}
8
ответ дан Community 16 August 2018 в 14:30
поделиться
  • 1
    Я нашел это как самое надежное решение для меня очень похожей проблемы. Я просто не хочу показывать изображение, чем показывать альтернативу с разбитым изображением. Благодарю. – pc_ 5 February 2018 в 00:07

У меня такая же проблема. Этот код хорошо работает в моем случае.

// Replace broken images by a default img
$('img').each(function(){
    if($(this).attr('src') === ''){
      this.src = '/default_feature_image.png';
    }
});
0
ответ дан Dale Nguyen 16 August 2018 в 14:30
поделиться

Это автономное решение:

$(window).load(function() {
  $('img').each(function() {
    if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
      // image was broken, replace with your new image
      this.src = 'http://www.tranism.com/weblog/images/broken_ipod.gif';
    }
  });
});
51
ответ дан Devon 16 August 2018 в 14:30
поделиться
  • 1
    Почти правильно ... правильное изображение в IE все равно будет возвращено (typeof (this.naturalWidth) == & quot; undefined & quot;) == true; - Я изменил оператор if на (! This.complete || (! $. Browser.msie & amp; & amp; (typeof this.naturalWidth == & quot; undefined & quot; this this.naturalWidth == 0))) – Sugendran 19 February 2009 в 03:42
  • 2
    это правило, потому что оно может обнаружить сломанное изображение после загрузки страницы. Мне это нужно. – northamerican 30 September 2013 в 15:51
  • 3
    @Sugendran $.browser устарел и удален сейчас, вместо этого использует обнаружение функции (в этом случае усложняется). – lee penkman 3 December 2014 в 23:20
  • 4
    Автономный, но требует jQuery? – Charlie 6 July 2016 в 18:12
  • 5
    Это отлично работает, но когда src изображения возвращает 204 No Content, это будет сломанное изображение. – Carson Reinke 4 October 2016 в 14:59

Это меня расстраивало годами. Мое исправление CSS устанавливает фоновое изображение на img. Если динамическое изображение src не загружается на передний план, то на вкладке img bg отображается метка. Это работает, если ваши изображения имеют размер по умолчанию (например, height, min-height, width и / или min-width).

Вы увидите значок сломанного изображения, но это улучшение. Протестировано до IE9 успешно. iOS Safari и Chrome даже не показывают сломанный значок.

.dynamicContainer img {
  background: url('/images/placeholder.png');
  background-size: contain;
}

Добавьте немного анимации, чтобы дать src время для загрузки без фонового мерцания. Chrome замирает в фоновом режиме плавно, но на рабочем столе Safari нет.

.dynamicContainer img {
  background: url('/images/placeholder.png');
  background-size: contain;
  -webkit-animation: fadein 1s;
  animation: fadein 1s;                     
}

@-webkit-keyframes fadein {
  0%   { opacity: 0.0; }
  50%  { opacity: 0.5; }
  100% { opacity: 1.0; }
}

@keyframes fadein {
  0%   { opacity: 0.0; }
  50%  { opacity: 0.5; }
  100% { opacity: 1.0; }
}
2
ответ дан Dylan Valade 16 August 2018 в 14:30
поделиться

Я использую встроенный обработчик error:

$("img").error(function () {
  $(this).unbind("error").attr("src", "broken.gif");
});

error() устарел в 1,8 или выше.

182
ответ дан kupendra 16 August 2018 в 14:30
поделиться
  • 1
    Если вы используете этот метод, вы можете использовать «один», метод, чтобы избежать необходимости развязывать событие: $ ('img'). one ('error', function () {this.src = 'broken.gif';}); – Prestaul 1 April 2011 в 17:18
  • 2
    +1 Но разве вы должны отвязать его? Он прекрасно работает с динамическими изображениями (например, теми, которые могут меняться при наведении), если вы не отвязываете его. – Aximili 5 April 2011 в 06:27
  • 3
    Я думаю, что если вы не отвязаете его, а ссылка на bluff.gif src никогда не будет загружаться по какой-либо причине, тогда в браузере могут произойти плохие вещи. – travis 5 April 2011 в 16:49
  • 4
    @travis, в какой момент вы сделаете этот звонок? Есть ли способ использовать этот метод и быть уверенным, что ваш обработчик подключается до возникновения ошибки? – Prestaul 5 September 2012 в 01:43
  • 5
    Вот пример случая, когда ошибка возникает перед обработчиком события: jsfiddle.net/zmpGz/1 Мне действительно любопытно, есть ли надежный способ прикрепления этого обработчика. .. – Prestaul 5 September 2012 в 02:03

Вот пример использования объекта HTML5 Image, завернутого JQuery. Вызовите функцию загрузки для основного URL-адреса изображения, и если эта загрузка вызывает ошибку, замените атрибут src изображения URL-адресом резервной копии.

function loadImageUseBackupUrlOnError(imgId, primaryUrl, backupUrl) {
    var $img = $('#' + imgId);
    $(new Image()).load().error(function() {
        $img.attr('src', backupUrl);
    }).attr('src', primaryUrl)
}

<img id="myImage" src="primary-image-url"/>
<script>
    loadImageUseBackupUrlOnError('myImage','primary-image-url','backup-image-url');
</script>
4
ответ дан Kurt Hartmann 16 August 2018 в 14:30
поделиться

Иногда использование события error не представляется возможным, например. потому что вы пытаетесь сделать что-то на уже загруженной странице, например, когда вы запускаете код через консоль, букмарклет или скрипт, загружаемый асинхронно. В этом случае проверка img.naturalWidth и img.naturalHeight равна 0.

Например, здесь приведен фрагмент для перезагрузки всех сломанных изображений с консоли:

$$("img").forEach(img => {
  if (!img.naturalWidth && !img.naturalHeight) {
    img.src = img.src;
  }
}
0
ответ дан Lea Verou 16 August 2018 в 14:30
поделиться

jQuery 1.8

// If missing.png is missing, it is replaced by replacement.png
$( "img" )
  .error(function() {
    $( this ).attr( "src", "replacement.png" );
  })
  .attr( "src", "missing.png" );

jQuery 3

// If missing.png is missing, it is replaced by replacement.png
$( "img" )
  .on("error", function() {
    $( this ).attr( "src", "replacement.png" );
  })
  .attr( "src", "missing.png" );

ссылка

3
ответ дан Nabi K.A.Z. 16 August 2018 в 14:30
поделиться

Я считаю, что это то, что вам нужно: jQuery.Preload

Вот пример кода из демонстрации, вы указываете загрузочные и не найденные изображения, и вы все установлено:

$('#images img').preload({
    placeholder:'placeholder.jpg',
    notFound:'notfound.jpg'
});
32
ответ дан Nick Craver 16 August 2018 в 14:30
поделиться
  • 1
    jQuery.Preload - это плагин, который должен использовать пример кода. – Dan Lord 18 September 2008 в 16:35
  • 2
    Да ... это связано в ответе на первой строке. – Nick Craver♦ 18 September 2008 в 17:03
  • 3
    Спасибо, Ник, похоже, это хорошее решение для 8+-летней проблемы Firefox, не показывающей замены изображения на сломанные изображения. Плюс вы можете заклеймить маленькую вещь ... еще раз спасибо. – blackhawk 8 August 2014 в 13:24

Я создал скрипт , чтобы заменить сломанное изображение с помощью события «onerror». Это может вам помочь.

    //the placeholder image url
    var defaultUrl = "url('https://sadasd/image02.png')";

    $('div').each(function(index, item) {
      var currentUrl = $(item).css("background-image").replace(/^url\(['"](.+)['"]\)/, '$1');
      $('<img>', {
        src: currentUrl
      }).on("error", function(e) {
        $this = $(this);
        $this.css({
          "background-image": defaultUrl
        })
        e.target.remove()
      }.bind(this))
    })
4
ответ дан Ninjaneer 16 August 2018 в 14:30
поделиться

Я решил проблему с этими двумя простыми функциями:

function imgExists(imgPath) {
    var http = jQuery.ajax({
                   type:"HEAD",
                   url: imgPath,
                   async: false
               });
    return http.status != 404;
}

function handleImageError() {
    var imgPath;

    $('img').each(function() {
        imgPath = $(this).attr('src');
        if (!imgExists(imgPath)) {
            $(this).attr('src', 'images/noimage.jpg');
        }
    });
}
9
ответ дан Peter Mortensen 16 August 2018 в 14:30
поделиться
  • 1
    Хорошая идея с попыткой перезагрузить изображения. Это полезно для загружаемых / автогенерированных изображений, и сервер, возможно, не получил / не завершил загрузку страницы. Это оригинальное форматирование. Немного слишком непоследовательно и не в моем вкусе, однако ... – Joakim 10 November 2014 в 14:04

Это дерьмовая техника, но она в значительной степени гарантирована:

<img ...  onerror="this.parentNode.removeChild(this);">
8
ответ дан Phil LaNasa 16 August 2018 в 14:30
поделиться

Я думаю, что у меня более элегантный способ делегирования событий и захвата событий на window error, даже если резервное изображение не загружается.

img {
  width: 100px;
  height: 100px;
}
<script>
  window.addEventListener('error', windowErrorCb, {
    capture: true
  }, true)

  function windowErrorCb(event) {
    let target = event.target
    let isImg = target.tagName.toLowerCase() === 'img'
    if (isImg) {
      imgErrorCb()
      return
    }

    function imgErrorCb() {
      let isImgErrorHandled = target.hasAttribute('data-src-error')
      if (!isImgErrorHandled) {
        target.setAttribute('data-src-error', 'handled')
        target.src = 'backup.png'
      } else {
        //anything you want to do
        console.log(target.alt, 'both origin and backup image fail to load!');
      }
    }
  }
</script>
<img id="img" src="error1.png" alt="error1">
<img id="img" src="error2.png" alt="error2">
<img id="img" src="https://i.stack.imgur.com/ZXCE2.jpg" alt="avatar">

Точка:

  1. Поместить код в head и выполнить как первый встроенный скрипт. Таким образом, он будет выслушивать ошибки после сценария.
  2. Использовать захват событий, чтобы уловить ошибки, особенно для тех событий, которые не пузырятся.
  3. Использовать делегирование делегаций, которое позволяет избежать привязки события на каждом изображении.
  4. Дайте элементу ошибки img атрибут после предоставления им backup.png, чтобы избежать исчезновения backup.png и последующего бесконечного цикла, как показано ниже:

img ошибка-> резервная копия.png-> ошибка-> резервная копия.png-> ошибка -> ,,,,,

1
ответ дан xianshenglu 16 August 2018 в 14:30
поделиться
$(window).bind('load', function() {
$('img').each(function() {
    if((typeof this.naturalWidth != "undefined" &&
        this.naturalWidth == 0 ) 
        || this.readyState == 'uninitialized' ) {
        $(this).attr('src', 'missing.jpg');
    }
}); })

Источник: http://www.developria.com/2009/03/jquery-quickie---broken-images.html

23
ответ дан XP84 16 August 2018 в 14:30
поделиться
;(window.jQuery || window.Zepto).fn.fallback = function (fallback) {
    return this.one('error', function () {
        var self = this;
        this.src = (fallback || 'http://lorempixel.com/$width/$height')
        .replace(/\$(\w+)/g, function (m, t) { return self[t] || ''; });
    });
};

Вы можете передать путь к заполнителю и получить в нем все свойства из объекта с неудачным изображением через $*:

$('img').fallback('http://dummyimage.com/$widthx$height&text=$src');

http://jsfiddle.net/ARTsinn / Cu4Zn /

2
ответ дан yckart 16 August 2018 в 14:30
поделиться

Pure JS. Моя задача состояла в том, что если образ «bl-once.png» пуст -> вставьте первый (который не имеет статуса 404) из списка массивов (в текущем каталоге):

<img src="http://localhost:63342/GetImage/bl-once.png" width="200" onerror="replaceEmptyImage.insertImg(this)">

Возможно, его нужно улучшить, но:

var srcToInsertArr = ['empty1.png', 'empty2.png', 'needed.png', 'notActual.png']; // try to insert one by one img from this array
    var path;
    var imgNotFounded = true; // to mark when success

    var replaceEmptyImage = {
        insertImg: function (elem) {

            if (srcToInsertArr.length == 0) { // if there are no more src to try return
                return "no-image.png";
            }
            if(!/undefined/.test(elem.src)) { // remember path
                path = elem.src.split("/").slice(0, -1).join("/"); // "http://localhost:63342/GetImage"
            }
            var url = path + "/" + srcToInsertArr[0];

            srcToInsertArr.splice(0, 1); // tried 1 src

            
                if(imgNotFounded){ // while not success
                    replaceEmptyImage.getImg(url, path, elem); // CALL GET IMAGE
                }
            

        },
        getImg: function (src, path, elem) { // GET IMAGE

            if (src && path && elem) { // src = "http://localhost:63342/GetImage/needed.png"
                
                var pathArr = src.split("/"); // ["http:", "", "localhost:63342", "GetImage", "needed.png"]
                var name = pathArr[pathArr.length - 1]; // "needed.png"

                xhr = new XMLHttpRequest();
                xhr.open('GET', src, true);
                xhr.send();

                xhr.onreadystatechange = function () {

                    if (xhr.status == 200) {
                        elem.src = src; // insert correct src
                        imgNotFounded = false; // mark success
                    }
                    else {
                        console.log(name + " doesn't exist!");
                        elem.onerror();
                    }

                }
            }
        }

    };

Итак, это будет вставьте правильный 'needed.png' в мой src или 'no-image.png' из текущего каталога.

4
ответ дан Дмитрий Дорогонов 16 August 2018 в 14:30
поделиться
  • 1
    Работает ли он в междоменном режиме? – jasxir 23 June 2017 в 09:38
  • 2
    Я использовал один и тот же сайт. Это просто идея. Мой реальный код был улучшен ... – Дмитрий Дорогонов 23 June 2017 в 12:44

Используя ответ Prestaul , я добавил несколько проверок, и я предпочитаю использовать способ jQuery.

<img src="image1.png" onerror="imgError(this,1);"/>
<img src="image2.png" onerror="imgError(this,2);"/>

function imgError(image, type) {
    if (typeof jQuery !== 'undefined') {
       var imgWidth=$(image).attr("width");
       var imgHeight=$(image).attr("height");

        // Type 1 puts a placeholder image
        // Type 2 hides img tag
        if (type == 1) {
            if (typeof imgWidth !== 'undefined' && typeof imgHeight !== 'undefined') {
                $(image).attr("src", "http://lorempixel.com/" + imgWidth + "/" + imgHeight + "/");
            } else {
               $(image).attr("src", "http://lorempixel.com/200/200/");
            }
        } else if (type == 2) {
            $(image).hide();
        }
    }
    return true;
}
8
ответ дан Community 17 August 2018 в 08:32
поделиться
  • 1
    Я нашел это как самое надежное решение для меня очень похожей проблемы. Я просто не хочу показывать изображение, чем показывать альтернативу с разбитым изображением. Благодарю. – pc_ 5 February 2018 в 00:07

Я не уверен, есть ли лучший способ, но я могу подумать о взломе, чтобы получить его - вы могли бы отправить сообщение Ajax на URL-адрес img и проанализировать ответ, чтобы увидеть, действительно ли изображение вернулось. Если он вернется как 404 или что-то еще, замените img. Хотя я ожидаю, что это будет довольно медленно.

9
ответ дан Peter Mortensen 17 August 2018 в 08:32
поделиться
  • 1
    Хорошая идея с попыткой перезагрузить изображения. Это полезно для загружаемых / автогенерированных изображений, и сервер, возможно, не получил / не завершил загрузку страницы. Это оригинальное форматирование. Немного слишком непоследовательно и не в моем вкусе, однако ... – Joakim 10 November 2014 в 14:04
Другие вопросы по тегам:

Похожие вопросы: