Обнаружение сбоя загрузки содержимого 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();
});