VueJS: Как динамически выполнять Javascript из строки?

1

Я пишу веб-сайт с помощью VueJS, который позволяет (выбранным) пользователям добавлять сценарии, которые автоматически выполняются при загрузке страницы. Вот пример текста, который пользователь может загрузить:

<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.5/howler.js"></script>
<script>
    var sound = new howler.Howl({
        src: ['./sample.mp3']
    )}.play();
</script>

Этот текст сохраняется в строке после извлечения из базы данных API. Проблема в том, что я не мог заставить ее выполнить, но я стараюсь. Есть ли опция в VueJS, которая может автоматически запускать javascripts в строках?

В качестве ссылки, здесь мой код:

var temp_arr = utils.preprocess(vm.chapterInfo.Content)
vm.display = temp_arr[0]
vm.control_script = console.log(temp_arr[1])

// None of below worked
eval(vm.control_script)
document.getElementsByTagName("head")[0].appendChild(control_script)
  • 3
    Хотя можно достичь того, чего вы хотите, не делайте этого, так как главное правило безопасности веб-приложений - запрещать пользователям запускать свои сценарии.
Теги:
vue.js

1 ответ

4
Лучший ответ

Проблема не в Vue, а в JavaScript.

Я предполагаю, что вы уже понимаете последствия безопасности, позволяющие пользователям запускать JavaScript; это редко бывает хорошей идеей. Такие сайты, как JSFiddle, делают это успешно, однако для обеспечения безопасности это потребует много работы и понимания, поэтому, если вы не на 100% уверены в том, что делаете, то, как сказал @WaldemarIce, вы не должны этого делать!

Правильно, с предупреждением, вам нужно сделать несколько вещей, чтобы заставить это работать:

1) Загрузите внешние скрипты:

loadScripts() {
    return new Promise(resolve => {

      let scriptEl = document.createElement("script");
      scriptEl.src = "https://cdnjs.cloudflare.com/ajax/libs/howler/2.0.5/howler.js";
      scriptEl.type = "text/javascript";

      // Attach script to head
      document.getElementsByTagName("head")[0].appendChild(scriptEl); 
      // Wait for tag to load before promise is resolved     
      scriptEl.addEventListener('load',() => {
        resolve();
      });
    });
  }

Здесь я просто привязываю внешний скрипт к заголовку документа и присоединяю событие load, которое разрешает Promise при загрузке.

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

executeScript() {
  // remove script tags from string (this has been declared globally)
  let script = string.replace(/<\/?script>/g,"")
  eval(script)
}

Сформируйте перспективу Vue, затем вы можете выполнить это внутри created крючка:

created() {
  this.loadScripts().then(() => {
    this.executeScript();
  });
},

Я оставлю это вам, чтобы извлечь внешние скрипты, которые вы хотите загрузить с вашего пользовательского ввода, но здесь JSFiddle: https://jsfiddle.net/49dq563d/

Ещё вопросы

Сообщество Overcoder
Наверх
Меню