Могу ли я использовать window.location.replace в iframe?


15

Мы можем использовать, window.location.replaceчтобы избежать истории и нацелить якоря на странице без перезагрузки страницы, но не в iframes?

Проблема заключается в нарушении CSP (политики безопасности контента), состояния которого script-src 'unsafe-inline'должны быть включены. За исключением того, что у меня нет определенного CSP, и даже если я определю его и разрешу, script-src 'unsafe-inline'он все равно выдаст ту же ошибку нарушения. Тот же результат в ie11 / chrome / ff.

Iframe в том же домене (в том же каталоге).

  1. Нацельтесь на iframe в консоли и используйте window.location.replace('/samepage.html#onpage_anchor')в консоли.
  2. оно работает. Он нацелен на привязку на странице без перезагрузки страницы и без истории.
  3. Поместите один и тот же код на якорные ссылки, и это работает.
  4. Используйте тот же код во внешнем скрипте, получите ошибку нарушения csp. Это отлично работает, если не в iframe.

Я попытался создать ПЕС , чтобы действие, но даже не в большинстве разрешающих политик безопасности контента возможно позволят его.


Изменить: поэтому я собрал примеры на plunker, который позволяет несколько файлов, чтобы я мог использовать правильные ссылки, которые ссылаются на родительские / дочерние страницы.

Примечания о примерах плунжера:

  1. Проблема не воспроизводится в этих примерах. Скрипт отлично работает даже в iframe. Однако тот же код не работает на моем локальном сервере, или когда я запускаю его в прямом эфире на VPS.

  2. Я подозреваю, что нарушение CSP не срабатывает на плункере, потому что плункер представляет контент браузеру через своего рода уровень абстракции.

  3. При первом нажатии на ссылки аккордеона в родительском приложении происходит обновление. Это связано с тем, что при первоначальной загрузке страницы она не ссылается на index.html. Последующие клики работают, как и ожидалось, без перезагрузки страницы. Не проблема в iframe, потому что он изначально ссылается на child.html

  4. Это хорошие примеры для демонстрации кода без необходимости внесения изменений в него (например, при необходимости изменить hrefs, чтобы они работали в фрагментах stackoverflow, упомянутых ниже). Это также хорошо, так как показывает, что JavaScript работает так, как должен. Но это не показывает на самом деле проблему. Вам все еще нужно будет загрузить его в свой редактор и запустить на локальном сервере или в среде живого хостинга, чтобы увидеть реальную проблему.

Плункер Примеры

С помощью сценария: без истории
Без сценария: с историей


Пример упрощенного кода

Простой баян с одной записью. Достаточно воспроизвести проблему.

Нажатие на кнопку «открыть / закрыть» развернет / свернет аккордеон, JS не требуется. JS должен делать то же самое, но без истории. Работает нормально, но не в фрейме.

Примечания к фрагменту кода:

  1. Вы можете запустить фрагмент, чтобы получить представление о том, что я описываю, но на самом деле это не демонстрирует проблему.

  2. Фрагмент не ведет себя так, как в реальном браузере, javascript не работает.

  3. Фрагмент показывает код, но он должен быть запущен в iframe, чтобы увидеть проблему. Запустите его вне iframe, чтобы увидеть разницу и как это должно работать.

  1. Из-за того, как ссылки работают с JS (заменяя весь URL-адрес), они на самом деле должны быть такими, href="https://stackoverflow.com/thispage.html#ac1"а не такими, href="#ac1"какими они отображаются в фрагменте (не могут быть нацелены на фактическую HTML-страницу в фрагменте). Поэтому, если вы попробуете это в вашем редакторе (пожалуйста, сделайте это), то не забудьте изменить ссылки на этот формат, this_document.html#anchor чтобы они оставались теми же якорями страниц, но page.html включен в ссылку.


Сценарий

$(document).ready(function() {

      // anchor links without history
      $.acAnch = function(event) {
        event.preventDefault();
        var anchLnk = $(event.target);
        var anchTrgt = anchLnk.attr('href');
        window.location.replace(anchTrgt);
      }
      // listen for anchor clicks
      $('.accordion').on('click', 'a', $.acAnch);

    });

Это очень просто:
1. Функция acAnch берет hrefатрибут и помещает его в window.location.replace().
2. Прослушайте щелчки на якорях в аккордеоне, чтобы запустить функцию acAnch.

Таким образом, все, что делает скрипт, это запустить window.location.replace('/this_same_page.html#on_page_anchor')

Если вы поместите это в консоль, это сработает, без нарушения CSP. Но запуск его из внешнего скрипта не работает.

Встроенные ссылки работают нормально:

onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"

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

Я попытался запустить javascript на parent, а не в iframe (с изменениями для выбора ссылок внутри дочернего элемента, конечно). Тот же результат ошибки CSP.


Почему я это делаю?

Ну, сайт гораздо сложнее, чем пример. Якоря в iframe работают нормально, но они добавляют историю. Если вы запустите приведенный выше код без javascript (или просто запустите фрагмент), откроете и закроете аккордеон несколько раз и нажмете кнопку «Назад», он вернется в состояние открытого закрытия.

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

Мне не нужно использовать location.replace, если есть другой метод, который будет работать. Я пробовал много других подходов и обнаружил, что методы, которые могут достичь того же результата, обычно приводят к той же ошибке.

Цель состоит в том, чтобы просто активировать якорные ссылки на странице без перезагрузки и без истории внутри iframe.

Встроенный скрипт работает. Можем ли мы заставить его работать во внешнем файле .js?


ты пытаешься просто добраться до якоря? если так, <a href="#ac0" class="ac-close">Close</a>должно работать.
Дементик

Хорошо, я настроил примеры на плункер. К сожалению, проблема не воспроизводится на плункере. Скорее сценарий работает нормально, даже в iframe. со скриптом - без истории и без скрипта есть история . Незначительная проблема по плункеру; Аккордеонные ссылки на родительском элементе вызывают обновление страницы, только при первом щелчке (изначально загружается без ссылки на index.html, поэтому после первого щелчка он работает, как и ожидалось, без перезагрузки страницы). Не проблема для iframe, так как он загружен с помощью child.html src.
Veneseme Tyras

Так что, по крайней мере, с примерами plunker вы можете увидеть полный код и посмотреть, как он должен работать. Это не работает на моем локальном сервере, хотя, или когда я запускаю его в прямом эфире на VPS. Я обновлю этот вопрос ссылками на плункер и информацией.
Veneseme Tyras

1
Я взял ваш пример кода на свой сервер, он работает нормально, затем я создал новые примеры плункеров из вашего примера plnkr.co/edit/V3kx7LQbTppaQ6V06uZp?p=preview, он также работает нормально. Нет ошибки CSP.
Мыслитель

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

Ответы:



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.