Как получить обновленный src iframe после взаимодействия

У меня есть тег iframe, связанный с графиком Grafana, который поддерживает взаимодействие (увеличение/уменьшение масштаба по оси X путем нажатия/двойного щелчка по iframe).

Когда я открываю URL-адрес src iframe на новой вкладке, я могу взаимодействовать с графиком и видеть, что параметры URL-адреса моего браузера продолжают обновляться с новыми значениями from/to (что указывает диапазон оси x графика). К сожалению, когда он находится в iframe, я не вижу никаких изменений в атрибуте «src» в любой ситуации. Мне нужно, чтобы изменения параметров URL применялись к другим отображаемым графикам (синхронизируйте их все).

Как я могу решить эту ситуацию?

Мой iframe в компоненте Angular.html:

<iframe [src] = "url_grafana_primary" width = "100%" height = "300" frameborder = "0"></iframe>

Iframe после рендеринга:

<iframe _ngcontent-c8 = "" frameborder = "0" height = "300" width = "100%" src = "http://146.250.180.213/grafana/dashboard-solo/script/script_graph.js?scenario_id=rrc_succ_rate&amp;cell_id=ESICAS23B_ESICAS23&amp;refresh=5s&amp;orgId=1&amp;panelId=4&amp;from=1555045266010&amp;to=1555168469864&amp;var-cell_id=ESICAS23B_ESICAS23&amp;var-scenario_id=ESICAS23B_ESICAS23"></iframe>

Некоторые скриншоты:

Вы можете видеть, что src сохраняет одно и то же значение в обеих ситуациях.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
0
2 476
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Атрибут src не меняется, но объект location должен вести себя так же, как если бы графана находилась за пределами iframe.

У вас есть 2 варианта,

  1. если кадр grafana и его родитель обслуживаются из одного и того же источника, вы можете получить доступ к объекту местоположения с помощью iframe.contentWindow.location.href.
  2. если они имеют разное происхождение, вам необходимо установить связь между фреймом и его родителем, вы можете использовать для этого postMessage.

проверьте этот пример: https://robertnyman.com/html5/postMessage/postMessage.html

Не могли бы вы привести пример того, как я могу использовать postMessage на Typescript?

denisb411 11.06.2019 13:15

Это не связано с Typescript, это API браузера. У вас есть примеры в MDN.

felixmosh 11.06.2019 16:03

я добавил пример

felixmosh 11.06.2019 18:45

Хорошо... так что я понял, что механизм "postMessage" работает только в том случае, если целевой URL-адрес готов получить это сообщение, верно? Если да, то, насколько мне известно, я не могу подготовить Grafana (сервер iframe) для ответа на это сообщение, поскольку я его не разрабатывал. Пожалуйста, поправьте меня, если это возможно.

denisb411 11.06.2019 21:20

Кроме того, со случайным сообщением я получаю эту ошибку: «Не удалось выполнить« postMessage »в« DOMWindow »: предоставленный целевой источник ('146.250.180.213') не соответствует источнику окна получателя ('локальный хост: 4201 ')».

denisb411 11.06.2019 21:25

Если вы не контролируете содержимое iframe, вы не можете postMessage быть родителем, вы правы.

felixmosh 11.06.2019 22:24

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

felixmosh 11.06.2019 22:25

Вы можете обнаружить событие onload, но чтобы получить URL-адрес, вам нужно будет сохранить файл cookie или localStorage.

var firstTimeLoad = true; // Because the function will call on the initial page

function iframeLoad(iframe) {
  if (firstTimeLoad) {
    firstTimeLoad = false;
    return;
  }
  alert("New page load");
}
<iframe width = "400" height = "244" src = "https://wooden-utensil.github.io/linkingSite1/" onload = "iframeLoad(this)" frameBorder = "0"></iframe> <!-- linkingSite1 contains a link (a href) that links to linkingSite2, and vice versa -->

Спасибо, но код в разделе «загрузка» не вызывается при обновлении содержимого iframe. Пробовал с `` <iframe [(src)] = "url_grafana_primary" onload = "alert('GRAPH LOADED')" id = "primary_iframe" width = "100%" height = "300" frameborder = "0" #primary_iframe> </iframe> `` и это не сработало.

denisb411 13.06.2019 13:06

@DenisCandido Я щелкнул правой кнопкой мыши iframe и нажал «Обновить фрейм», и у меня появилось окно предупреждения. Я не знаю, почему он не отображается для вас?

mekb 14.06.2019 06:32

iframe Grafana работает по-другому. Вы можете взаимодействовать с ним, но он не «обновляется». Он обновляет свои значения, но не запускает общее обновление. Я не знаю, как это работает, и сообщество Grafana мне тоже не помогает.

denisb411 14.06.2019 15:48

В случае, если вы не являетесь владельцем контента в iframe, вы мало что можете сделать. Лучшее, что вы можете сделать, это создать цикл (setInterval), который будет сравнивать значение с последним значением, которое вы видели.

<iframe #graph></iframe>
@ViewChild('graph', { static: true }) graph!: ElementRef<HTMLIFrameElement>;

private srcWatcher = new Observable(observer => {
  const interval = setInterval(() => {
    observer.next(this.graph && this.graph.nativeElement && this.graph.nativeElement.src);
  }, 10);

  return () => clearInterval(interval);
}).pipe(
  distinctUntilChanged(),
);

Имея observable как этот, вы теперь можете реагировать на любые изменения в нем.

ПРИМЕЧАНИЕ: Я бы также предложил, чтобы наблюдаемый объект выполнялся за пределами zoneJS, если тайм-аут интервала должен быть низким. В противном случае Angular запускал бы обнаружение глобальных изменений на каждом интервале. Под глобальным я подразумеваю, что он будет проверять все приложение, все поддеревья, которые используют стратегию обнаружения изменений по умолчанию.

К сожалению, не работал. srcWatcher никогда не срабатывает.

denisb411 17.06.2019 16:02

@DenisCandido Извините, это никоим образом не возможно, это функция безопасности.

Akxe 17.06.2019 16:13

Вам просто нужно установить src iframe на тот же старый src. Возможно, вам придется добавить переменную строки запроса со случайным числом, например с отметкой времени, чтобы избежать проблем с кэшированием.

function refresh(){
		var iframe = document.getElementById('myframe');
		iframe.src = iframe.src;
	}
iframe{
width:100%;
height:300px;
}
<p>
	<button onclick = "refresh()">Refresh</button>
</p>
<iframe id = "myframe" src = "https://www.chartjs.org/samples/latest/charts/line/basic.html" frameborder = "0"></iframe>

Другие вопросы по теме