执行用包含脚本标签的 XMLHttpRequest 编写的 Javascript?

Posted

技术标签:

【中文标题】执行用包含脚本标签的 XMLHttpRequest 编写的 Javascript?【英文标题】:Executing Javascript written with XMLHttpRequest that contains script tags? 【发布时间】:2012-02-24 20:13:48 【问题描述】:

通过 javascript 请求,XMLHttpRequest 会响应一些需要添加到请求页面的额外 Javascript。

使用 eval(),如果响应类似于:

alert('This is the js response');

...那么这样就可以了。

但是,返回的文本可能如下所示:

<script language="javascript">var checkVar='checkVar: value 1';</script>

但很可能:

<script src="http://www.somesite.com/setCheckVarValue.js"></script> 

...需要在页面上加载额外的JS。

我已确保 XMLHttpRequestsynchronous,因为我想在此之后引用 checkVar。

所以:

<script type="text/javascript" src="http://www.mysite.com/addJSToPage.js" />
// at this point, since this is a synchronous call, page processing waits
// until the response is received that needs to include the additional JS
// to load; this, for testing sets the value of checkVar

<script type="text/javascript" >
    alert(checkVar);
</script>

警报消息应为“checkVar: value 1”。

由于其他原因,这并不像在addJSToPaged.js 中设置var checkVar 那样简单,所以我不是在寻找那种建议。

我只是使用 alert(checkVar) 作为测试,以确保在响应中通过 JS 设置了一个值。

我想我可以去掉开始和结束脚本标签并保留eval() 的方式。但是,我想知道是否有任何解决方案支持我正在寻找的东西?

谢谢。

更新

按照 Prashanth 的建议,我在 addJSToPage.js 中添加了:

var dynamicElement = document.createElement('div');

然后在 XMLHttpRequest 的响应中,我做了:

dynamicElement.appendChild = xmlhttp.responseText;

仍然没有看到 checkVar 的值。

【问题讨论】:

您可能需要将其注入 DOM,eval 是邪恶的。在这种情况下,您可能需要使用消息进行响应并在响应文本上发出警报。 @Prashanth - 这不像警报那么简单;更新了描述,因为响应将是加载更多 JS 的 JS 引用。 对了,注入到dom中就可以调用函数了。我想不出一个有效的用例,你只需要用 javascript 来响应。 上面更新了,但是还是不行。可以举个例子吗? 【参考方案1】:

忽略您所做的任何事情都可能是个坏主意这一事实,Prashanth 将其插入到 DOM 中的想法是正确的。你也可以去掉标签,只评估为“正常”。

不要忽略以下事实:1) eval 是邪恶的,2) 动态加载远程代码是不好的,3) 同步 AJAX 是非常糟糕的,我想说:

除非您知道自己在做什么,否则evaling 任何事情都是一个坏主意,它很难调试,可能会暴露出大量的安全漏洞和各种其他问题。然后,您通过加载远程代码来复合这一点,这显然是以您无法控制的方式生成的,因为您无法仅获取脚本。同步 Ajax 很糟糕,因为 javascript 中只有一个线程,阻塞 Ajax 会从字面上锁定 整个 页面直到它被加载,因为即使像滚动这样的事情也会生成 javascript 事件,而当前繁忙的引擎必须这样做检查处理程序。虽然请求在您的本地计算机上进行得很快,但连接速度慢或质量差的人可能会等待一段时间,直到连接超时。 AJAX 中的“A”是异步的,并且有充分的理由使用回调,它们的存在是有原因的。

如果您只是进行数据传递,请使用 JSON,它是 JavaScript 对象表示法,一种简单的数据格式,恰好也是有效的 JavaScript。你可以在上面使用eval,但我建议使用 JSON 解析器,我认为大多数现代浏览器都内置了它们(这里可能是错误的)。 JSON 很好,因为它可以表达复杂的数据结构,易于生成和解析,并且得到广泛支持。

【讨论】:

我明白你在说什么。我最初使用的是 asynch 方法,但正如我所提到的,我想确保响应文本(这是一个 JS ref)被执行。 除此之外,我发现 eval() 存在问题,因为它只允许您从自己的域执行脚本。我认为集成 jQuery 的 getScript() 可能是一个更好的解决方案,并避免了许多讨论的陷阱。 想一想,它不仅仅是可以添加的 Javascript 包含。本质上,我需要能够将任何额外的 html(可能是带有标签的完整 javascript)注入到 Javascript 的页面中。 Prashanth 的选择可能是正确的选择。【参考方案2】:

这是一个例子

var script = document.createElement("script");
//innerHTML can be the response from your server. But send the text with script tag.
script.innerHTML = "var foo = function()console.log('injected into the DOM')" 
document.body.appendChild(script) // insert into the DOM
foo() // call the function 

【讨论】:

为了进一步澄清,我发布了这个:***.com/questions/9125163/…。它可能不仅仅是一个JS函数,而是加载一个JS库,或者图像等。有什么建议吗?【参考方案3】:

重述 - 需要能够在加载之后/期间将某些内容动态加载到页面上,并让它执行。通过执行,我不仅仅意味着更改某些 div 上的文本 - 这很容易。但是如果我们想动态加载一些新的 JS,比如说来自某个外部源的警报,并注入它,连同它的脚本标签,也许还有一些其他 HTML 代码,那么解决方案是使用以下 jQuery 调用:

jQuery(dynamicResponse).appendTo('body');

dynamicResponse 来自异步 $.ajax()XmlHttpRequest 响应。一旦出现,它就会被附加到任何 DOM 元素上,在 appendTo() 中指定并执行。

【讨论】:

以上是关于执行用包含脚本标签的 XMLHttpRequest 编写的 Javascript?的主要内容,如果未能解决你的问题,请参考以下文章

外部脚本必须包含 <script> 标签吗?

为啥我不能在 IE 中将包含脚本标签的字符串添加到 innerHTML

首先执行啥?它是php标签内的脚本还是HTML?

自动单击包含相同文本和标签的页面上的多个按钮

Cors XmlHttpRequest 和响应

javascript:取消各种请求