Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VueJS:如何从字符串动态执行Javascript?_Javascript_Vue.js - Fatal编程技术网

VueJS:如何从字符串动态执行Javascript?

VueJS:如何从字符串动态执行Javascript?,javascript,vue.js,Javascript,Vue.js,我正在使用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();

我正在使用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>

问题不是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();
      });
    });
  }
在这里,我只是将外部脚本附加到文档的头部,并附加一个加载事件,该事件在加载时解析

2) 现在我们已经加载了外部脚本,我们可以执行脚本的其余部分。您需要去掉脚本标记,以便执行以下操作:

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

我将让您从用户输入中提取要加载的外部脚本,但这里有一个JSFiddle:

问题不是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();
      });
    });
  }
在这里,我只是将外部脚本附加到文档的头部,并附加一个加载事件,该事件在加载时解析

2) 现在我们已经加载了外部脚本,我们可以执行脚本的其余部分。您需要去掉脚本标记,以便执行以下操作:

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

我将让您从用户输入中提取要加载的外部脚本,但这里有一个JSFiddle:

我最近遇到了这个问题,不得不扩展@craig_h的答案。下面的示例允许以字符串形式发送完整的嵌入代码(HTML元素以及脚本和内联JS)。这是在使用



从“Vue”导入Vue;
导出默认值{
...
方法:{
克隆属性(元素,源节点){
让attr;
让attributes=Array.prototype.slice.call(sourceNode.attributes);
while(attr=attributes.pop()){
setAttribute(attr.nodeName、attr.nodeValue);
}
}
},
安装的(){
if(this.embedString&&this.embedString.length>0)
{
//将API中给出的代码解析到一个新的DOM中,以便我们可以轻松地对其进行操作
var parser=新的DOMParser();
var htmlDoc=parser.parseFromString(this.embedString,'text/html');
//获取新DOM主体的内容并循环。
//我们希望将所有HTML元素添加到页面并运行/加载所有JS
var kids=[…htmlDoc.body.children];
让len=kids.length;
对于(变量i=0;i
我最近遇到了这个问题,不得不扩展@craig_h的答案。下面的示例允许以字符串形式发送完整的嵌入代码(HTML元素以及脚本和内联JS)。这是在使用



从“Vue”导入Vue;
导出默认值{
...
方法:{
克隆属性(元素,源节点){
让attr;
让attributes=Array.prototype.slice.call(sourceNode.attributes);
while(attr=attributes.pop()){
setAttribute(attr.nodeName、attr.nodeValue);
}
}
},
安装的(){
if(this.embedString&&this.embedString.length>0)
{
//将API中给出的代码解析到一个新的DOM中,以便我们可以轻松地对其进行操作
var parser=新的DOMParser();
var htmlDoc=parser.parseFromString(this.embedString,'text/html');
//获取新DOM主体的内容并循环。
//我们希望将所有HTML元素添加到页面并运行/加载所有JS
var kids=[…htmlDoc.body.children];
让len=kids.length;
对于(变量i=0;i<div ref="htmlDump"></div>
<script>
import Vue from "vue";
export default {
  ...
  methods: {
    cloneAttributes(element, sourceNode) {
      let attr;
      let attributes = Array.prototype.slice.call(sourceNode.attributes);
      while(attr = attributes.pop()) {
        element.setAttribute(attr.nodeName, attr.nodeValue);
      }
    }
  },
  mounted(){
    if(this.embedString && this.embedString.length > 0)
    {
      //Parse the code given from the API into a new DOM so we can easily manipulate it
      var parser = new DOMParser();
      var htmlDoc = parser.parseFromString(this.embedString, 'text/html');
      //Get the contents of the new DOM body and loop through.
      //We want to add all HTML elements to the page and run / load all JS
      var kids = [...htmlDoc.body.children];
      let len = kids.length;
      for (var i = 0; i < len; i++) {
        var item = kids[i];
        if(item.tagName == "SCRIPT")
        {
          //If we have a 'src' attribute then we're loading in a script
          if(item.hasAttribute('src'))
          {
            //Create a new element within the current doc to trigger the script load
            let scriptEl = document.createElement("script");
            //Copy all attributes from the source element to the new one
            this.cloneAttributes(scriptEl, item);
            //Attach script to the DOM to trigger it to load
            this.$refs.htmlDump.appendChild(scriptEl);
          } else {
            //if we don't have a 'src' attribute then we have some code to run
            eval(item.innerText);
          }
        } else{
          this.$refs.htmlDump.appendChild(item);
        }
      }
    }
  }
  ...
}
</script>