Обнаружение сбоя загрузки содержимого iframe

Я могу обнаружить, когда содержимое iframe загрузилось с использованием события загрузки. К сожалению, для моих целей есть две проблемы:

  • При ошибке при загрузке страницы (404/500 и т.д.) событие загрузки никогда не запускается.
  • Если некоторые изображения или другие зависимости не удалось загрузить, событие загрузки запускается как обычно.

Есть ли какой-то способ, который я могу надежно определить, произошла ли какая-либо из вышеупомянутых ошибок?

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

Ответ 1

Если у вас есть контроль над страницей iframe (а страницы находятся на одном доменном имени), стратегия может быть следующей:

  • В родительском документе инициализируйте переменную var iFrameLoaded = false;
  • Когда документ iframe загружен, установите эту переменную в родительский объект в true, вызывая из документа iframe родительскую функцию (setIFrameLoaded();, например).
  • проверьте флаг iFrameLoaded с помощью объекта timer (установите таймер на ваш предпочтительный предел времени ожидания). Если флаг по-прежнему является ложным, вы можете сказать, что iframe не был регулярно загружен.

Надеюсь, это поможет.

Ответ 2

У меня была эта проблема в последнее время, и мне пришлось прибегнуть к настройке действия опроса Javascript на родительской странице (содержащей тег IFRAME). Эта функция JavaScript проверяет содержимое IFRAME для явных элементов, которые должны существовать только в ответе GOOD. Это предполагает, конечно, что вам не придется иметь дело с нарушением "той же политики происхождения".

Вместо того, чтобы проверять все возможные ошибки, которые могут быть созданы из множества разных сетевых ресурсов. Я просто проверил, что один постоянный положительный Элемент (я), который, как я знаю, должен быть в хорошем ответе.

После заранее определенного времени и/или неудачных попыток обнаружения ожидаемых элементов (-ов) JavaScript изменяет атрибут IFRAME SRC (чтобы запросить у моего сервлета) страницу, удобную для пользователя, в отличие от отображения типичного Сообщение HTTP ERROR. JavaScript также может легко изменить атрибут SRC, чтобы сделать совершенно другой запрос.

function checkForContents(){
var contents=document.getElementById('myiframe').contentWindow.document
if(contents){
    alert('found contents of myiframe:' + contents);
    if(contents.documentElement){
        if(contents.documentElement.innerHTML){
            alert("Found contents: " +contents.documentElement.innerHTML);
            if(contents.documentElement.innerHTML.indexOf("FIND_ME") > -1){
                openMediumWindow("woot.html", "mypopup");
            }
        }
    }
}

}

Ответ 3

Я думаю, что событие страницы будет запущено для страниц с ошибками. Или, если вы делаете это с хром, тогда проверьте свой запрос слушателя прогресса, чтобы узнать, является ли он HTTP-каналом, в этом случае вы можете получить код состояния.

Как и для зависимостей страниц, я думаю, вы можете сделать это только с помощью chrome, добавив захват onerror-прослушивателя событий, и даже тогда он будет обнаруживать ошибки только в элементах, а не в фоновых рисунках CSS или других изображениях.

Ответ 4

Идентификатор для самого верхнего (body) элемента на странице, загружаемой в ваш iframe.

в обработчике загрузки вашего iframe, проверьте, не возвращает ли getElementById() ненулевое значение. Если это так, iframe загрузился успешно. иначе он потерпел неудачу.

в этом случае поместите frame.src= "about: blank". Перед тем, как это сделать, обязательно удалите загрузчик.

Ответ 5

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

Он не совсем использует событие загрузки, но может определить, доступен ли сайт и доступен ли он (если он есть, то теоретически iFrame должен загружаться).

Сначала я решил сделать вызов AJAX, как и все остальные, за исключением того, что он сначала не работал у меня, поскольку я использовал jQuery. Он отлично работает, если вы выполните XMLHttpRequest:

var url = http://url_to_test.com/
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status != 200) {
        console.log("iframe failed to load");
    }
};
xhttp.open("GET", url, true);
xhttp.send();

Edit:
Таким образом, этот метод работает нормально, за исключением того, что он имеет множество ложных негативов (собирает много вещей, которые будут отображаться в iframe) из-за малярии с перекрестным происхождением. Способ, которым я обходился, состоял в том, чтобы сделать CURL/Web-запрос на сервере, а затем проверить заголовки ответов для a), если сайт существует, и b) если заголовки установили x-frame-options.

Это не проблема, если вы запускаете свой собственный веб-сервер, так как вы можете сделать свой собственный api-вызов для него.

Моя реализация в node.js:

app.get('/iframetest',function(req,res){ //Call using /iframetest?url=url - needs to be stripped of http:// or https://
   var url = req.query.url; 
    var request = require('https').request({host: url}, function(response){ //This does an https request - require('http') if you want to do a http request
        var headers = response.headers;
        if (typeof headers["x-frame-options"] != 'undefined') {
            res.send(false); //Headers don't allow iframe
        } else {
            res.send(true); //Headers don't disallow iframe
        }
    });
    request.on('error',function(e){
       res.send(false); //website unavailable
    });
    request.end();
});