【问题标题】:javascript from ajax doesn't get proper execution来自 ajax 的 javascript 无法正确执行
【发布时间】:2016-09-21 08:46:04
【问题描述】:

使用 Ajax,我创建了一种控制台,允许我动态执行一些 PHP 函数。

看起来像这样

问题是在一堆命令之后,控制台变得难以阅读。所以我创建了一个名为“wipe();”的javascript函数,它清除了包含控制台的<div>

我用chrome的developpers工具(javascript控制台)测试了这个功能,效果很好。

但是当我尝试通过使 PHP-AJAX 返回“”来调用此函数时,它不起作用。它什么都不做。

我在互联网上读到所有“”彼此独立工作,但您可以从另一个 块调用<script>function</script>

那么为什么它没有这样做呢?

这里是php代码:

    echo '<script>wipe();</script>';

这是第一个

        var xmlhttp = new XMLHttpRequest();
        var span = document.getElementById("screen");

     function send(data) {
        window.setInterval(function() {
        var elem = document.getElementById('screen');
           xmlhttp = new XMLHttpRequest();
           xmlhttp.open("GET", "./_rcons-transmetter.php?data="+data, true)
           xmlhttp.onloadend = function() {
             span.innerHTML = span.innerHTML+escapeHtml(data)+'<br>'+xmlhttp.responseText+'<br><br>';
           }
           xmlhttp.send();
         }

    function wipe(){
             span.innerHTML = '';
        }

【问题讨论】:

  • 任何控制台错误?
  • 没有控制台错误。什么都没有,事实上。就像一切都运行良好(但事实并非如此)。
  • 在wipe函数体中做一个console.log(span)
  • 当我从 AJAX 调用时,console.log 不会出现在控制台中,但是当我从控制台调用它时会出现。
  • 通过innerHTML设置时忽略脚本标签

标签: javascript php jquery html ajax


【解决方案1】:

为避免安全问题(如cross-site scripting 攻击)HTML5 指定通过innerHTML should not execute 插入&lt;script&gt; 标记。

执行脚本的一种方法是使用 eval() 评估 html。警告:使用 eval 可能很危险。

var xmlhttp = new XMLHttpRequest();
var span = document.getElementById("screen");

function send(data) {
  window.setInterval(function() {
      var elem = document.getElementById('screen');
      xmlhttp = new XMLHttpRequest();
      xmlhttp.open("GET", "./_rcons-transmetter.php?data=" + data, true)
      xmlhttp.onloadend = function() {
        span.innerHTML = span.innerHTML + escapeHtml(data) + '<br>' + xmlhttp.responseText + '<br><br>';
        evalJSFromHtml(span.innerHTML);
      }
      xmlhttp.send();
    }

    function wipe() {
      span.innerHTML = '';
    }

    function evalJSFromHtml(html) {
      var newElement = document.createElement('div');
      newElement.innerHTML = html;

      var scripts = newElement.getElementsByTagName("script");
      for (var i = 0; i < scripts.length; ++i) {
        var script = scripts[i];
        eval(script.innerHTML);
      }
    }

  }

【讨论】:

  • 如果使用不当会产生安全问题(例如:xss)。关于这个有很多线程(stackoverflow.com/questions/197769/…
  • 我很惊讶这个答案被接受了 - evalJSFromHtml 无法访问发送函数中的wipe 函数!
  • @JaromandaX - 我相信“eval”函数只有在严格模式下才能访问全局函数。既然他不是在严格模式下应该没问题的。
  • eval 可以在严格函数中使用,并且仍然可以访问全局环境,只需使用一种奇怪的语法来执行 indirect eval -- @987654329 @
【解决方案2】:

直接从“发送”函数调用“擦除”函数作为回调函数。检查 status = 200 以获得成功响应。

var xmlhttp = new XMLHttpRequest();
    var span = document.getElementById("screen");

 function send(data) {
    window.setInterval(function() {
    var elem = document.getElementById('screen');
       xmlhttp = new XMLHttpRequest();
       xmlhttp.open("GET", "./_rcons-transmetter.php?data="+data, true)
       xmlhttp.onloadend = function() {
         span.innerHTML = span.innerHTML+escapeHtml(data)+'<br>'+xmlhttp.responseText+'<br><br>';
       }

    xmlhttp.onreadystatechange = function()
    {
     if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
      {
        wipe(); // 'Wipe' callback function
      }
    }
       xmlhttp.send();
     }


function wipe(){
         span.innerHTML = '';
    }

【讨论】:

    【解决方案3】:

    但是当我尝试通过使 PHP-AJAX 返回“wipe();”来调用此函数时,它不起作用。它什么都不做。

    尝试创建脚本标签并添加到文档而不是更改内部 html。

    var spaScript = document.getElementById("spaScript");
    var wraper = document.createElement("div");
    wraper.innerHTML = xmlhttp.responseText;
    var script = document.createElement("script");
    script.innerHTML = wraper.getElementsByTagName("script")[0].innerHTML;
    spaScript.appendChild(script);

    【讨论】:

    • 查看 Niks 的帖子方法而不是我的帖子。
    【解决方案4】:

    测试wipe() 是否在输入中,是否触发它而不是ajax 调用

        var xmlhttp = new XMLHttpRequest();
        var span = document.getElementById("screen");
    
        function send(data) {
          if (data.indexOf('wipe()') == -1) {
    
            window.setInterval(function() {
                var elem = document.getElementById('screen');
                xmlhttp = new XMLHttpRequest();
                xmlhttp.open("GET", "./_rcons-transmetter.php?data=" + data, true)
                xmlhttp.onloadend = function() {
                  span.innerHTML = span.innerHTML + escapeHtml(data) + '<br>' + xmlhttp.responseText + '<br><br>';
                }
                xmlhttp.send();
              }
            } else {
              wipe();
            };
          }
    
          function wipe() {
            span.innerHTML = '';
          }
    

    【讨论】:

      【解决方案5】:

      直接在元素内插入脚本标签不应该起作用(顺便在控制台中生成错误)。

      在响应文本上使用本机 eval() 函数而不指定标记属性应该可以解决问题。

      在服务器端

      echo 'wipe()';
      

      在客户端

      eval(xmlhttp.responseText)
      

      【讨论】:

        猜你喜欢
        • 2020-03-02
        • 2014-02-20
        • 2013-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-27
        • 1970-01-01
        相关资源
        最近更新 更多