Wordpress PhP отображает пользовательский код, полученный функцией get_field() ACF в iframe

На сайте eMy wordpress есть настраиваемый тип записи под названием tool, который имеет три настраиваемых поля с именами html, css и js. Этот тип сообщения инструмента отображается на моем сайте с помощью пользовательского шаблона и шорткода, который отображает содержимое полей html, css и js в iframe. Этот шорткод создается функцией в моем файле functions.php, и упрощенная версия этой функции выглядит так:

function renderTool() {
return '
<html>

  <head>

    <script

      src = "https://kit.fontawesome.com/c48c422dea.js"

      crossorigin = "anonymous"

    ></script>

    <style>

      .container {background:blue;}

    </style>

  </head>

  <body>

    <div id = "container" class = "container">

      <div id = "tool" class = "tool cssreset">

      <iframe src = "data:text/html;charset=utf-8,' . 
  '<html>
    <head>
      <style>' . htmlspecialchars(get_field("css")) . '</style>
      <script>' . htmlspecialchars(get_field("js")) . '</script>
    </head>
    <body>' . htmlspecialchars(get_field("html")) . '</body>
  </html>'
        . '"></iframe>

      </div>

      <div class = "bar" id = "bar">

         <i class = "toggle fa fa-solid fa-expand"></i>

      </div>

    </div>

    <script>

      function myfunction() {

console.info("hello world");

         }

           </script>

  </body>

  </html>';
}

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

Я поговорил об этом с чатом openai, и он порекомендовал мне сохранить содержимое iframe в отдельном html-файле, а затем установить iframe src в этот html-файл как таковой:


$css = htmlspecialchars(get_field("css"));

$js = htmlspecialchars(get_field("js"));

$html = htmlspecialchars(get_field("html"));

// Create the inner document and save it to a separate file

$inner_document = '

  <html>

    <head>

      <style>

        '. $css .' 

      </style>

      <script>

        '. $js .' 

      </script>

    </head>

    <body>

      '. $html .' 

    </body>

  </html>

';

file_put_contents('inner-document.html', $inner_document);

// Use the inner document as the src for the iframe

return '<iframe src = "inner-document.html"></iframe>';

Эта идея мне уже не нравится, потому что кажется, что она еще больше все усложняет. Когда я пытался использовать этот код, iframe вместо этого отображал страницу, на которой я был, и в ней такой же сломанный iframe. iframeception.

Еще одна вещь, которую я пробовал, заключалась в передаче html, который должен быть в iframe внутри urlencode как таковой: (это фрагмент, этот код заменит iframe в моем текущем подходе)

<iframe src = "data:text/html;charset=utf-8,' . urlencode(
  '<html>
    <head>
      <style>' . htmlspecialchars(get_field("css")) . '</style>
      <script>' . htmlspecialchars(get_field("js")) . '</script>
    </head>
    <body>' . htmlspecialchars(get_field("html")) . '</body>
  </html>'
        ) . '"></iframe>

Это просто отобразило его как необработанный текст, по крайней мере, в правильные элементы html (посмотрите https://prnt.sc/4I24tFgxQ56m)

Чтобы уточнить, эти get_field() функции взяты из плагина WordPress под названием acf, см. документацию здесь: https://www.advancedcustomfields.com/resources/get_field/

Из всей этой информации я пришел к выводу, что ошибка должна быть связана с тем, что строковые литералы не экранированы должным образом и, следовательно, конфликтуют с/вызывают возврат остальных значений в строковом формате. Тем не менее, я надеялся, что htmlspecialchars решит эту проблему, но это помогло только с рендерингом CSS. В моем текущем решении я помещаю весь код, который хочу отобразить, в источник iframe, используя URL-адрес данных, поэтому закрывающий тег iframe идет после содержимого iframe.

Чтобы вы могли лучше представить, что я пытаюсь донести, вот ссылка на страницу, которая страдает этой ошибкой: https://tropical.team/tools/calculator. Возможно, у меня все еще есть тестовый код, поэтому вы увидите что-то немного отличающееся от того, что я описал, но я попытаюсь изменить его на это, когда вернусь.

Вчера я болтал с

В вашем исходном коде внутри возвращаемой строки есть echo. Кроме того, открывающий тег вашего iframe установлен неправильно — он находится за пределами строки, которую вы возвращаете.

FiddlingAway 01.01.2023 16:08

@FiddlingAway это были просто опечатки, поскольку этот код является переделанной копией фактического кода, они не вызывают проблемы, поскольку этих ошибок не существует в фактическом коде, я исправил это сейчас

treepek 01.01.2023 16:56

Так проблема решена? Я перешел по вашей ссылке, и калькулятор отображается правильно (хотя в консоли есть ошибка JS, но я предполагаю, что вы работаете над ней в это время).

FiddlingAway 01.01.2023 17:02

HTML отображается, а css и js - нет, проверьте элемент инструмента и просмотрите его содержимое, вы можете увидеть, что некоторый код отображается как текст, вычисленный считается правильно обработанным, когда он имеет желтый фон и работает, так что теперь его только 1/3

treepek 01.01.2023 17:15

Ваш открывающий тег iframe все еще не закрыт. Вам не хватает > после объявления кодировки. Кроме того, вместо этого htmlspecialchars(...) используйте это htmlspecialchars_decode(...), если HTML-контент, хранящийся в вашей БД, прошел htmlspecialchars перед вставкой в ​​БД.

FiddlingAway 01.01.2023 17:22

Он закрыт, посмотрите еще раз, но на самом деле я не помещаю весь код в iframe, я помещаю его в значение src в качестве URL-адреса данных, потому что размещение его внутри iframe (между начальным и закрывающим тегами) не делает что-либо.

treepek 01.01.2023 19:22

Да, я пропустил ту часть о том, что HTML находится внутри src, извините за это. В таком случае, как насчет использования urlencode(...)? Вам это нужно, потому что вы устанавливаете его как содержимое файла src. Пожалуйста, посмотрите это изображение , чтобы понять, что я имею в виду. urlencoded версия HTML также используется в этом ответе SO.

FiddlingAway 01.01.2023 19:35

Я пробовал это, но потом он тоже сломался: prnt.sc/4I24tFgxQ56m

treepek 02.01.2023 12:28

Не уверен, почему это происходит. Давайте пока откажемся от этого маршрута, попробуем еще кое-что, а потом я сдамся. Глядя на ваш сгенерированный код, я заметил, что элемент script внутри iframe использует кавычки для своего атрибута src. Я думаю, что это может нарушить ваш код — пожалуйста, посмотрите это изображение, если это звучит так, как будто я не имею никакого смысла. Решение этого было бы только временным решением, так как оно сработает только в этом случае - urlencode должно было сработать изначально, и я, честно говоря, не знаю, почему это не сработало.

FiddlingAway 02.01.2023 12:52

Я исправил эту часть jsut, потому что мой плагин кэширования, как обычно, превращал мою жизнь в ад, я исключил модификации js-файлов для этих страниц, и теперь javascript правильно добавлен в заголовок. Калькулятор по-прежнему не работает, и в настоящее время я пытаюсь выяснить, является ли это ошибкой с PHP или просто фактическим кодом калькулятора.

treepek 02.01.2023 12:54

Хорошо, рад, что вы решили эту часть. После публикации моего предыдущего комментария я понял, в чем проблема с urlencode — пробелы закодированы как +, и поэтому вы видели их повсюду. Я должен был порекомендовать rawurlencode - это будет кодировать пробелы как %20. Что касается выполнения скрипта - пожалуйста, ознакомьтесь с этим ТАКИМ вопросом и соответствующими ответами.

FiddlingAway 02.01.2023 13:02

Я только что попытался использовать rawurlencode, и он лучше, но все еще не работает, просмотрите tropical.team/tool/calculator-2-0 и prnt.sc/tynlQTNv9JAh

treepek 02.01.2023 13:19

Визуализированное тело вашего iframe, кажется, содержит HTML-документ внутри с содержимым, которое выглядит так, как будто оно было просмотрено htmlcharacters(). Можете ли вы проверить свой фоновый код, в частности этот: get_field("html"), и убедиться, что он не содержит ничего похожего на <html><head>...</head><body>....</body></html>?

FiddlingAway 02.01.2023 13:35

это так, каждый раз, когда это будет, я думаю, использование srcdoc было бы более подходящим

treepek 02.01.2023 13:39

@FiddlingAway есть идеи, как я могу справиться с тем фактом, что js не работает, я предполагаю, что это потому, что ссылки document.somrthing не применяются к фреймам, но относится ли это и к srcdoc?

treepek 02.01.2023 19:04

Потому что это внедрение скрипта - попробуйте.

FiddlingAway 03.01.2023 10:26
Поведение ключевого слова "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) для оценки ваших знаний,...
0
16
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вместо того, чтобы передавать html в качестве URL-адреса данных, лучше использовать атрибут srcdoc для iframe. Это позволяет вам передать ему строку (html) и отобразить ее правильно. Вам придется сохранить функцию htmlspecialchars, потому что в противном случае двойные кавычки, которые могут быть возвращены get_field в том виде, в каком он отправлен пользователем, завершат строку значения srcdoc.

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