2011-07-22 24 views
0

编辑:已解决,请参阅下面的答案。使用jsonp提取运行脚本标记

我试图解决的问题是广告加载脚本,它用jsonp加载广告代码并将其插入到dom中。

现在有时广告代码会包含javascript标签,并从一些帖子在这里stackoverflow我有这样的想法,将它们移动到文档的头,使他们运行,这一些实验后,促使我问这个问题:

Appending scripts to head using javascript - weird behavior

我的问题没有得到解决,但问题仍然存在,我插入脚本到我的测试DIV不能运行,也没有运行时移动到头部。

我这里有一个代码示例:

http://m.iijax.com/p1.html

和简单的JSONP例子在这里:

http://m.iijax.com/p2.php

在P2上的代码将尝试登录信息到控制台,提醒消息,然后设置一个变量,然后我尝试打印出来,所有这些事情都失败了。

是使用eval函数运行这样的代码的唯一方法,还是我在做一些基本的错误?

这里是第一部分的代码:

<!DOCTYPE html> 
<html> 
<head> 
<script type="text/javascript"> 
if (typeof JSONP === 'undefined') { 
    /*Lightweight JSONP fetcher - www.nonobtrusive.com*/ 
    var JSONP = (function(){ 
     var counter = 0, head, query, key, window = this; 
     function load(url) { 
      var script = document.createElement('script'), 
       done = false; 
      script.src = url; 
      script.async = true; 

      script.onload = script.onreadystatechange = function() { 
       if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { 
        done = true; 
        script.onload = script.onreadystatechange = null; 
        if (script && script.parentNode) { 
         script.parentNode.removeChild(script); 
        } 
       } 
      }; 
      if (!head) { 
       head = document.getElementsByTagName('head')[0]; 
      } 
      head.appendChild(script); 
     } 
     function jsonp(url, params, callback) { 
      query = "?"; 
      params = params || {}; 
      for (key in params) { 
       if (params.hasOwnProperty(key)) { 
        query += encodeURIComponent(key) + "=" + encodeURIComponent(params[key]) + "&"; 
       } 
      } 
      var jsonp = "json" + (++counter); 
      window[ jsonp ] = function(data){ 
       callback(data); 
       window[ jsonp ] = null; 
       try { 
        delete window[ jsonp ]; 
       } catch (e) {} 
      }; 

      load(url + query + "callback=" + jsonp); 
      return jsonp; 
     } 
     return { 
      get:jsonp 
     }; 
    }()); 
} 
JSONP.get('http://m.iijax.com/p2.php', { requestType:'demoRequest'}, function(data){ 
    var adC = document.getElementById("testId"); 
    adC.innerHTML = data.code; 
    // Move script tags to head 
    var scripts = adC.getElementsByTagName("script"); 
    for(i=scripts.length - 1;i>-1;i--) { 
     document.head.appendChild(scripts[i]); 
    } 
    // Now check value of var letsSeeIfThisIsDefined, set in the fetched code 
    console.log(letsSeeIfThisIsDefined); 
}); 
</script> 
</head> 
<body> 
    <div id="testId"></div> 
</body> 
</html> 

回答

1

多亏了这个帖子:

Executing <script> elements inserted with .innerHTML

我能够修改我的代码一点,我现在挑出来的数据从使用jsonp获取的脚本标记中,将它放入新创建的脚本标记中并将它们附加到头部并且它可以工作。 :)

下面是修改后的代码,其中包括新的功能parseScripts():

<!DOCTYPE html> 
<html> 
<head> 
<script type="text/javascript"> 
function parseScripts(elementId) { 
    // Get the div where code has been inserted by innerHTML 
    var td = document.getElementById(elementId); 
    // Find any script tags in that code 
    var scripts = td.getElementsByTagName("script"); 
    for(i=scripts.length - 1;i>-1;i--) { 
     // For each script found pick out the data 
     var elem = scripts[i]; 
     var data = (elem.text || elem.textContent || elem.innerHTML || ""); 
     // Create a new script element and add the data 
     var script = document.createElement("script"); 
     script.type = "text/javascript"; 
     try { 
      // doesn't work on ie... 
      script.appendChild(document.createTextNode(data));  
     } catch(e) { 
      // IE has funky script nodes 
      script.text = data; 
     } 
     // Append new script tag to head of document 
     document.head.appendChild(script); 
    } 
} 

if (typeof JSONP === 'undefined') { 
    /*Lightweight JSONP fetcher - www.nonobtrusive.com*/ 
    var JSONP = (function(){ 
     var counter = 0, head, query, key, window = this; 
     function load(url) { 
      var script = document.createElement('script'), 
       done = false; 
      script.src = url; 
      script.async = true; 

      script.onload = script.onreadystatechange = function() { 
       if (!done && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) { 
        done = true; 
        script.onload = script.onreadystatechange = null; 
        if (script && script.parentNode) { 
         script.parentNode.removeChild(script); 
        } 
       } 
      }; 
      if (!head) { 
       head = document.getElementsByTagName('head')[0]; 
      } 
      head.appendChild(script); 
     } 
     function jsonp(url, params, callback) { 
      query = "?"; 
      params = params || {}; 
      for (key in params) { 
       if (params.hasOwnProperty(key)) { 
        query += encodeURIComponent(key) + "=" + encodeURIComponent(params[key]) + "&"; 
       } 
      } 
      var jsonp = "json" + (++counter); 
      window[ jsonp ] = function(data){ 
       callback(data); 
       window[ jsonp ] = null; 
       try { 
        delete window[ jsonp ]; 
       } catch (e) {} 
      }; 

      load(url + query + "callback=" + jsonp); 
      return jsonp; 
     } 
     return { 
      get:jsonp 
     }; 
    }()); 
} 

JSONP.get('http://m.iijax.com/p2.php', { requestType:'demoRequest'}, function(data){ 
    var adC = document.getElementById("testId"); 
    adC.innerHTML = data.code; 
    // Try and run the scripts 
    parseScripts("testId"); 
}); 

</script> 
</head> 
<body> 
    <div id="testId"></div> 
    <div style="height: 0px; width: 0px; border: 10px solid transparent; border-left-color: #505050;"></div> 
</body> 
</html> 
+0

我认为你缺少具有“src”脚本的src标记 – James

4

答案似乎有点臃肿。这里的my version

function execJSONP(url, cb) { 
    var script = document.createElement('script'); 
    script.async = true; 
    var callb = 'exec'+Math.floor((Math.random()*65535)+1); 
    window[callb] = function(data) { 
     var scr = document.getElementById(callb); 
     scr.parentNode.removeChild(scr); 
     cb(data); 
     window[callb] = null; 
     delete window[callb]; 
    } 
    var sepchar = (url.indexOf('?') > -1)?'&':'?'; 
    script.src = url+sepchar+'callback='+callb; 
    script.id = callb; 
    document.getElementsByTagName('head')[0].appendChild(script); 
} 
相关问题