Доступ к iframe с разных доменов.
Добрый день. У меня На странице есть iframe, вот он:
<iframe id="include_content" src="https://menu.food24h.ru" width="100%" frameborder="0"></iframe> Пытаюсь получить к нему доступ по средствам jquery, вот так:
$('iframe#include_content').contents()
В результате выхватиываю ошибку: Uncaught DOMException: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://bistro-obed.ru" from accessing a cross-origin frame Из этого я понимаю что сайт на котором у меня установлен iframe против того что бы я получил доступ к нем. Пишу в заголовках и на первом и на втором сайте, вот это:
<?
header('Access-Control-Allow-Origin: *');
header('Origin: *');
?>
Но ошибка все равно остается, подскажите пожалуйста что делаю не так |
Попробуйте передать такие заголовки:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Credentials: true');
|
smart-create,
Добавьте на сайте в iframe:
window.addEventListener('message', function(e) {
if(e.origin === 'http://bistro-obed.ru') {
eval(e.data);
}
});
На основном сайте:
var frame = document.getElementById('include_content');
var evalCode = 'console.log(document.body)';
frame.contentWindow.postMessage(evalCode, '*');
Таким образом, Вы передаёте во iframe любой код, который хотите там выполнить. |
laimas, увы не помогло, я сам не понимаю почему, казалось бы должно все работать..., Вы случайно не знаете не может ли быть проблема в том что сайт bistro-obed.ru на котором я размещаю iframe работает на битриксе? может быть у битрикса есть какие то вшитые директивы запрещающие лезть в iframe?
|
ruslan_mart, спасибо за подсказку. Но у меня есть проблема с пониманием того как это должно работать.
То есть я беру код:
window.addEventListener('message', function(e) {
if(e.origin === 'http://bistro-obed.ru') {
eval(e.data);
}
});
вставляю его на сайт menu.food24h.ru (это страница которую я вставляю в iframe) а этот код:
var frame = document.getElementById('include_content');
var evalCode = 'console.log(document.body)';
frame.contentWindow.postMessage(evalCode, '*');
я вставляю на сайт bistro-obed.ru (стайт на на который я устанавливаю iframe с сайта menu.food24h.ru) Пожалуйста подскажите, правильно ли я все понял и сделал? Если да, то что я должен получить в итоге и как мне с этим работать? Я к сожалению пока не совсем понимаю как этот метод работает( |
Цитата:
Сайт ваш точно отдает добавленные заголовки, проверяли? |
laimas, дописал в методы OPTIONS и добавил header('Content-Type: text/html').
Проверил на обоих стайтах наличие добавленных заголовков, все на месте. Вот заголовки сайта на который вставляю iframe, а вот заголовки сайта который вставляю в iframe. Ошибка при вызове .contents() не меняется..( |
Что значит заголовки сайта и заголовки в iframe? Разрешение нужно для фрейма, а это отдельный запрос. Вы можете просто в .htassecc определить передачу этих заголовков и они будут передаваться всегда, давая разрешения на доступ. Здесь в учебнике описан механизм кроссдоменных запросов.
|
laimas, прошу прощения я не совсем правильно сформулировал свою мысль. Я просто хотел ответит на ваш предыдущий вопрос: "Да, я проверил заголовки которые добавил сайт отдает".
На счет htassecc, можно и через него конечно, но мне привычнее прямо на странице прописывать заголовки. Главное ведь что сайт их отдает? А каким образом их прописали по моему не имеет значения, поправьте меня если я не прав. А вот дальше я увы не понял что вы хотел сказать упоминаю кросс доменные запросы. Я понимаю как работают кросс доменные запросы, но я ведь не запросы делаю, я просто пытаюсь получить доступ к iframe, что бы можно было выполнять с его содержимым действия с помощью js. Я уже десятки раз использовал на страницах сайтов разные iframe и выполнял с ними действия с помощью .contents(). Всегда для этого хватало:
<?
header('Access-Control-Allow-Origin: *');
header('Origin: *');
?>
Я не понимаю что в этот раз пошло не так.., по этому и обратился за советом. |
Цитата:
Насчет "я же просто хочу", так исполнять или нет ваши желания браузер и определяет на основе обмена заголовками с сервером. Все в общем то в порядке. Попробуйте ради эксперимента выполнить Ajax запрос, данные будут доступны? |
laimas, проверил, отправил простой get, ответ получил в виде html кода запрашиваемой страницы. Во общем запросы проходят. Но как это может помочь получить доступ к iframe?
|
Значит браузер накладывает ограничения на iframe, и в его контексте заголовки не решат проблемы. Знаю, что в IE можно добавить домен в доверенные, и заголовков не потребуется. Не знаю как программно это обойти, в сети значит есть описание проблемы и ее обхода. Плохо то, что у каждого браузера свое понимание, и надо полагать и решений потребуется не одно.
|
laimas, а вариант который предлагал ruslan_mart нельзя использовать? Как по мне подход вполне действенный, просто я не до конца понимаю как с ним работать
|
Цитата:
|
IFrame:
(function() {
var actions = {
getContent: function() {
return document.documentElement.innerHTML;
}
};
window.addEventListener('message', function(e) {
if(e.origin === 'http://bistro-obed.ru') {
var data = JSON.parse(e.data);
if(data.action in actions) {
data.result = actions[data.action]();
parent.postMessage(JSON.stringify(data), '*');
}
}
});
})();
Основной сайт:
(function() {
var frame = document.getElementById('include_content');
var callbackList = {
handleContent: function(result) {
var contents = (new DOMParser).parseFromString(result, 'text/html');
console.log(contents);
}
};
window.addEventListener('message', function(e) {
if(e.origin === 'https://menu.food24h.ru') {
var data = JSON.parse(e.data);
if(data.callback in callbackList) {
callbackList[data.callback](data.result);
}
}
});
frame.addEventListener('load', function() {
var data = {
action: 'getContent',
callback: 'handleContent'
};
frame.contentWindow.postMessage(JSON.stringify(data), '*');
});
})();
|
| Часовой пояс GMT +3, время: 14:28. |