调用从 Ajax 响应返回的 JavaScript 函数

IT技术 javascript ajax function
2021-01-12 00:34:51

我有一个发送 Ajax 命令的系统,该命令返回一个包含函数的脚本块。将此数据正确插入 DIV 后,我希望能够调用此函数来执行所需的操作。

这可能吗?

6个回答

我认为在这种形式下正确解释您的问题:“好吧,我已经完成了所有 Ajax 的工作;我只想知道我的 Ajax 回调插入到 DIV 中的 JavaScript 函数是否可以从那一刻起随时调用,也就是说,我不想在上下文中调用它到回调返回”。

好的,如果您的意思是这样,那么答案是肯定的,您可以在浏览器中的页面持久化期间的任何时刻调用您的新代码,在以下条件下:

1) 你的 Ajax 回调返回的 JavaScript 代码必须在语法上没问题;
2) 即使您的函数声明被插入到<script>现有<div>元素中块中,浏览器也不会知道新函数的存在,因为声明代码从未被执行过。因此,您必须eval()通过 Ajax 回调返回您的声明代码,以便有效地声明您的新函数并使其在整个页面生命周期内可用。

即使很傻,这段代码也解释了这个想法:

<html>
    <body>
        <div id="div1">
        </div>
        <div id="div2">
            <input type="button" value="Go!" onclick="go()" />
        </div>
        <script type="text/javascript">
            var newsc = '<script id="sc1" type="text/javascript">function go() { alert("GO!") }<\/script>';
            var e = document.getElementById('div1');
            e.innerHTML = newsc;
            eval(document.getElementById('sc1').innerHTML);
        </script>
    </body>
</html>

我没有使用 Ajax,但概念是一样的(即使我选择的例子肯定不是很聪明:-)

一般来说,我不质疑您的解决方案设计,即在单独的 .js 文件中外部化 + 泛化该功能是否或多或少合适,但请注意,这样的解决方案可能会引发更多问题,尤其是如果你的 Ajax 调用应该重复,即如果同一个函数的上下文应该改变或者如果声明的函数持久性应该被关注,那么也许你应该认真考虑将你的设计更改为这个线程中建议的示例之一。

最后,如果我误解了你的问题,并且当你的 Ajax 回调返回时你正在谈论函数的上下文调用,那么我的感觉是建议krosenvold 描述的 Prototype 方法,因为它是跨浏览器的,经过测试并且功能齐全,这可以为您提供更好的未来实施路线图。

精湛的答案真的节省了我的时间。上帝祝福你。
2021-03-12 00:34:51
@Typel 在这里使用 eval() 有任何安全风险吗?
2021-03-13 00:34:51
这在示例中有效,因为所有内容都在同一页面中,并且时间没有发挥作用。它不适用于实际使用 AJAX 方法调用外部文件进行处理的任何内容,因为 eval() 函数在外部进程有时间返回响应之前运行。
2021-03-17 00:34:51
@Anupam 我认为普遍的共识是 eval() 始终存在与之相关的安全风险 - 我会注意它是否以及如何使用。就个人而言,我不会将它与 AJAX 结合使用以避免打开任何 XSS 漏洞。在大多数情况下,如果我需要从 AJAX 返回执行一个函数,我只会将参数传回,让函数的内容驻留在调用页面中并从调用页面执行(或类似的东西)。
2021-04-08 00:34:51

注意: eval() 很容易被误用,假设请求被第三方拦截并向您发送不可信的代码。然后使用 eval() 您将运行这个不受信任的代码。请参阅此处了解eval()危险


在返回的 HTML/Ajax/JavaScript 文件中,您将有一个 JavaScript 标记。给它一个 ID,比如runscript向这些标签添加 id 并不常见,但需要专门引用它。

<script type="text/javascript" id="runscript">
    alert("running from main");
</script>

在主窗口中,然后通过仅评估新的 JavaScript 代码块(在本例中,它称为runscript)来调用 eval 函数

eval(document.getElementById("runscript").innerHTML);

它可以工作,至少在 Internet Explorer 9 和 Google Chrome 中是这样。

实施此解决方案是否存在任何安全漏洞?
2021-03-21 00:34:51
在 2018 年仍然存在:这听起来很危险,就像“默默无闻的安全”。如果我正在攻击您的站点并注意到 eval() 函数,那么我肯定会注意到那里的 ID 标签并修改我的攻击以仅在您的<script id="my-secure-id">标签中插入 malicios 代码使用此解决方案,我没有看到任何额外的安全性。事实上,它只会给你一种虚假的安全感,这更加危险。但是大约 6 年后,HTTPS 现在变得更加普遍。我相信通过安全的 HTTPS 攻击 eval() 是不可能的。我这样假设错了吗?
2021-03-23 00:34:51
太棒了,一直在努力解决这个问题 +1
2021-03-24 00:34:51
我一直试图解决这个问题几个小时,只是遇到了这个答案!这太棒了,可能应该被接受!谢谢,+1 :)
2021-03-25 00:34:51
显然 eval 在某些情况下是危险的,但是如果有人在假设您没有运行 ssl 的情况下拦截您的代码并将一些代码注入到 eval 中,那么如果您的响应返回插入的 HTML,那么他们不能做同样的事情有什么正当理由进入 DOM(他们可以只添加一个脚本标签)。在我看来,对来自服务器的响应运行 eval 与服务器为您提供插入到 DOM 中的 HTML 具有相同的安全隐患。或许有一些不同。
2021-04-04 00:34:51

这是完全可能的,甚至有一些相当合法的用例。使用Prototype框架按如下方式完成。

new Ajax.Updater('items', '/items.url', {
    parameters: { evalJS: true}
});

请参阅Ajax 更新程序的文档选项位于公共选项集中像往常一样,有一些关于“this”指向哪里的警告,所以请阅读细则。

JavaScript 代码将在加载时进行评估。如果内容包含功能,myFunc(), 您真的可以myFunc()事后也许如下。

if (window["myFunc"])
   myFunc()

这将检查该函数是否存在。也许有人有更好的跨浏览器方式来完成在 Internet Explorer 6 中的工作。

这太棒了!谢谢!我一直使用更新程序上的“onSuccess”函数来手动评估 Javascript。但这更具可读性并且适用于所有浏览器。
2021-03-26 00:34:51

这对于您的代码来说似乎是一个相当奇怪的设计 - 通常让您的函数直接从 .js 文件中调用更有意义,然后只使用 Ajax 调用检索数据。

但是,我相信它应该通过对响应调用eval()工作- 只要它是语法正确的 JavaScript 代码。

使用 jQuery 我会使用getScript