Коротко: напрямую получить доступ к DOM iframe можно только если страница в iframe и родитель находятся в одном происхождении (same origin — одинаковые протокол/домен/порт). Если Grafana загружается с другого происхождения — браузер заблокирует доступ (Same‑Origin Policy). Ниже — что можно сделать и примеры.
1) Если Grafana и родитель — same origin
- Можно читать/писать DOM через iframe.contentWindow / iframe.contentDocument.
Пример:
const iframe = document.getElementById('grafana-iframe');
iframe.addEventListener('load', () => {
try {
const doc = iframe.contentDocument || iframe.contentWindow.document;
console.log('title:', doc.title);
// пример: получить элемент по селектору внутри iframe
const el = doc.querySelector('.dashboard-container');
console.log(el);
} catch (err) {
console.error('Ошибка доступа к iframe:', err);
}
});
2) Если Grafana — другой origin (частый случай)
- Прямой доступ к DOM невозможен. Варианты:
a) PostMessage — родитель и страница в iframe обмениваются сообщениями через window.postMessage. Это работает только если встраиваемая страница умеет слушать и отвечать на сообщения. Графана «из коробки» такого API обычно не предоставляет, так что это маловероятно без модификации Grafana (плагин, кастомный HTML и т. п.).
Пример (родитель):
iframe.contentWindow.postMessage({type:'hello'}, 'https://grafana.example.com');
window.addEventListener('message', e => {
if (e.origin !== 'https://grafana.example.com') return;
console.log('message from iframe', e.data);
});
Пример (получатель в iframe) — должен быть вставлен в страницу Grafana:
window.addEventListener('message', e => { /* проверка e.origin */; e.source.postMessage({ok:true}, e.origin); });
b) Proxy/same‑origin hosting — самый рабочий вариант: проксируете Grafana под тот же домен/порт, что и родитель, или поддомен, настроенный как тот же origin. Тогда браузер считает страницы одним origin и доступ возможен. Для этого:
- Настройте nginx/apache проксирование (proxy_pass) так, чтобы URL вашего сайта/iframe был тем же origin.
- В grafana.ini включите allow_embedding (security.allow_embedding = true).
- Убедитесь, что ни nginx, ни Grafana не выставляют X-Frame-Options: DENY/SAMEORIGIN, или настройте заголовки так, чтобы фрейм работал.
Пример nginx:
location /grafana/ {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Frame-Options; # или proxy_set_header X-Frame-Options "";
}
c) Получать данные через Grafana API и отрисовывать их в родительской странице (без iframe).
3) Встраивание iframe с сохранением атрибутов
Ниже — пример тега iframe, подходящий для встраивания панели/dash в страницу (замените src на ваш URL: /d-solo/... или /dashboard/...):
<iframe
id="grafana-iframe"
src="https://grafana.example.com/d-solo/abcd1234/my-dashboard?panelId=2&orgId=1&kiosk"
width="100%"
height="800"
frameborder="0"
scrolling="no"
allowfullscreen
style="border:0; display:block;"
></iframe>
Пара замечаний:
- Для «чистой» панели используйте /d-solo/ (single panel) или параметры ?kiosk=tv, чтобы убрать лишний UI.
- Если Grafana требует авторизации, iframe покажет логин. Для seamless embed включите анонимный доступ или используйте проксирование/авторизацию на сервере.
- Проверьте заголовки: X-Frame-Options и Content-Security-Policy frame-ancestors — они могут блокировать встраивание. Настройте Grafana/proxy чтобы разрешить встраивание.
4) Безопасность
- Открытие доступа к содержимому iframe (same origin) означает, что другая сторона может читать cookie/локальные данные — учитывайте это.
- Используйте postMessage и проверяйте origin в обработчиках.
Если хотите, пришлите конкретный iframe-код и URL Grafana (и укажите, находятся ли они на одном домене), и я покажу точную конфигурацию nginx или пример кода для доступа/обмена сообщениями.