【问题标题】:javascript eval intrinsic restrictions?javascript eval 内在限制?
【发布时间】:2011-10-07 06:36:59
【问题描述】:

我有一种情况,我必须在 Javascript 中使用 eval。是的,我知道它是邪恶的,但在这种情况下它是必需的,因为有两个必要条件:

  1. Javascript 代码很大。
  2. 仅在少数情况下需要对其进行评估(和下载),因此我不希望始终下载脚本,而是按需下载。

有了这些必要条件,我编写了一个 XMLHttpRequest 来请求代码 (600+K),并且我想立即评估该代码。正如我稍后将展示的,脚本只包含要插入两个变量的数据。问题是评估这个 javascript 总是失败并出现语法错误。如果我逐字输入代码(没有 eval),代码执行得很好。这是最小的例子。我有一个像这样的search.js 文件:

// search.js for functional mind. Generated statically
// from the set of posts.
posts = { 'postlist' : ['<a href="XXX">YYY</a>', 'other link...' ] };
posts_for_word = { 'word1' : [0,1], 'word2' : [Z,K] }; 

最后一个变量posts_for_word 包括包含该词的帖子的索引。当我在 eval 中评估 Javascript 时,问题就来了:

// global environment
var posts = {}; // Initial value, empty
var posts_for_word = {}; // same

function() {
var request = // create XMLHTTPREQUEST request
var response = // obtain response (the javascript)
eval( response ); // <- syntax error
// access posts or posts_for_word
posts.postlist[ posts_for_word['word1'][0] ]
....
}

问题:

  1. 当我使用 eval 评估上面显示的 javascript 时,firefox 告诉我它在第一行中的格式不正确。
  2. 然后我移除了 cmets。我认为 eval 会评估它,就好像它是一个普通的 Javascript 程序,但它似乎不接受 cmets(为什么?)。
  3. 删除 cmets 后,代码可以运行,但 Firefox 的 Javascript 控制台仍然告诉我第一行(定义 JSON 第一个变量)存在语法错误。为什么?

【问题讨论】:

  • 在需要时加载 javascript 的常用方法是在 DOM 中插入一个新的 script 标签。是否有理由说明这对您的情况不起作用?
  • @cobbal,我先试过了。那一刻我可能做错了什么。我会再试一次,但它不起作用(我插入了脚本,但在下一个 javascript 行中找不到变量)。无论如何,eval 的问题仍然悬而未决。

标签: javascript json eval


【解决方案1】:

您不应该使用 AJAX 和 eval() 在您的网站上创建脚本,而是创建一个带有文件链接的 &lt;script&gt; 元素并将其附加到正文:

(function() {
    var jsCode = document.createElement('script');
    jsCode.setAttribute('src', 'http://localhost/tests/doStuff.js');
    document.body.appendChild(jsCode);
}());

(这段代码实际上是直接取自我的一个书签,效果很好。)

至于变量作用域,如果你在你的内部文件中将它们声明为var variable,它将覆盖文件作用域并变成全局的。


但是,如果您需要同步加载脚本,则必须(尽管这被认为是不好的做法)使用同步 AJAX 调用。如何做到这一点已经写在我面前了,Dynamically loading JavaScript synchronously

【讨论】:

  • 谢谢,陆道仙人。我也试过那个选项。问题是该脚本是异步检索的,而紧跟动态DOM 操作的行看不到新变量。看起来由于代码很大,加载需要很长时间,而 Firefox 总是异步执行此操作。结果:该代码之后的行没有找到该变量。过了一段时间,我再试一次,变量 is 在那里。现在,即使我添加了jsCode.setAttribute('async', '');,脚本也会异步加载。
  • 现在这更有意义了。让我试试(感谢指点!)
  • 没问题。添加到我的答案中以供将来用户参考。
  • 它确实有效。谢谢!我知道同步加载可能被认为是不好的做法,但是如果我需要这些值并希望按需加载它们该怎么办?过几天我会接受你的回答。我仍然保持打开状态,因为我真的知道为什么eval 不支持 cmets。此外,即使脚本有效,我也会遇到语法错误......
猜你喜欢
  • 1970-01-01
  • 2010-10-07
  • 2020-08-30
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
相关资源
最近更新 更多