Чи можу я використовувати window.location.replace в iframe?


15

Ми можемо використовувати window.location.replaceдля уникнення історії та націлювання на якірні сторінки без перезавантаження сторінок, але не в iframe?

Проблема полягає в порушенні 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, який дозволяє кілька файлів, щоб я міг використовувати належні hrefs, які посилаються на батьківські / дочірні сторінки.

Примітки щодо прикладів планку:

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

  2. Я підозрюю, що порушення CSP не спрацьовує на plunker, оскільки plunker представляє вміст у браузері через якийсь шар абстракції.

  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 не буде. Але запустити його із зовнішнього скрипту не працює.

Inline за посиланнями працює добре:

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

Якщо встановити, що на відповідних посиланнях працює чудово , але я дійсно вважаю за краще не використовувати вбудований сценарій, як це. Має бути спосіб зробити це за допомогою зовнішнього сценарію.

Я спробував запустити javascript на батьківському, а не в iframe (з модифікаціями, щоб вибрати посилання в дочірніх програмах). Той самий результат помилки CSP.


Чому я це роблю?

Ну сайт набагато складніший за приклад. Якіри в iframes добре працюють, але вони додають історію. Якщо ви запускаєте код вище без JavaScript, (або просто запустіть фрагмент), відкрийте та закрийте акордеон кілька разів та скористайтесь кнопкою "Назад", вона повернеться через відкриті закриті стану.

Я не заперечував би проти історії, але якщо вона знаходиться в кадрі iframe, коли ви залишаєте батьківську сторінку і повертаєтесь до неї, історія в iframe порушена. Повернення вже не повертається через стан гармошок, а натомість просто продовжує перезавантажувати кадр iframe. Спочатку прив’язки не спричиняють перезавантаження iframe, а лише кроки через історію стану гармошок, яка працює добре, поки ви не залишите сторінку та не повернетесь назад. Потім назад вже не проходить через стани гармошки, а просто проходить через купу однакових iframe-перезавантажень. Це дуже недоброзичлива поведінка користувачів.

Мені не потрібно використовувати location.replace, якщо є інший метод, який буде працювати. Хоча я спробував багато інших підходів, і я виявив, що методи, які можуть досягти однакового результату, як правило, призводять до тієї ж помилки.

Мета - просто активувати якірні посилання на сторінці без перезавантаження та без історії, всередині iframe.

Вбудований сценарій працює. Чи можемо ми змусити його працювати у зовнішньому файлі .js?


ти намагаєшся просто досягти якоря? якщо так, то <a href="#ac0" class="ac-close">Close</a>має працювати.
Дементік

Добре, я налаштовую приклади на plunker. На жаль, проблема не відтворена на планку. Скоріше, сценарій працює чудово, навіть у кадрі. зі сценарієм - без історії та без сценарію немає історії . Незначний випуск на plunker; акордеоні посилання на батьківській програмі викликають оновлення сторінки, натиснувши лише перший раз (спочатку завантажують планку без посилання index.html, тож після першого клацання воно працює як очікувалося, без перезавантаження сторінок). Не є проблемою для iframe, оскільки він завантажений з child.html src.
Венесема Тирас

Отож, принаймні, на прикладах планку ви можете побачити повний код і побачити, як він повинен працювати. Він не працює на моєму локальному сервері, або коли я запускаю його на VPS. Я оновлю питання за допомогою посилань на планкер та інформацію.
Венесема Тирас

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

Так, добре, це добре працює і на планку. Мені цікаво, як це працює на вашому сервері, тому що після вашого коментаря я потрійно перевірив, і я не можу змусити його працювати на моєму сервісі або на моєму локальному сервері.
Veneseme Tyras

Відповіді:



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.