我正在通过jQuery的.ajax(...)
调用从另一台服务器(跨域)加载并执行脚本。
其他服务器的代码执行之后,需要执行一些代码,因为否则某些对象“未定义”。
可能很重要:远程代码确实包含另一个getScript(...)
来电。而且我必须等待这个代码也被执行。我不能简单地从我的代码加载第二个脚本,因为它的源是动态的(即取决于远程脚本的某些结果)。
success
回拨显然,在远程代码加密后会调用success
回调,但之前远程代码执行。
# coffee script
executeLater = ->
# this bit of code needs to run after the remote code has been executed.
console.log("yehaa!")
$.getScript("http://example.com/script-from-other-server.js")
.success(executeLater) # this gets executed when the remote script is loaded,
# but before the remote script is executed.
async: false
显然,对于跨域请求,async
属性会被忽略,如jQuery文档中所述:http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
此外,我想避免async: false
设置,因为据说它会阻止浏览器。
# coffee script
executeLater = ->
# this bit of code needs to run after the remote code has been executed.
console.log("yehaa!")
$.ajax(
dataType: 'script',
url: 'http://example.com/script-from-other-server.js',
async: false # does not work because the request is cross domain
)
.success(executeLater)
$.when(...).then(...)
使用jQuery的when-then mechanism,显然,{strong} 之前执行<{1}}代码执行。
then
# coffee script
executeLater = ->
# this bit of code needs to run after the remote code has been executed.
console.log("yehaa!")
$.when( $.ajax(
dataType: 'script',
url: 'http://example.com/script-from-other-server.js',
) ).then(executeLater)
两个脚本我不能在生产中这样做,正如我在上面的“背景”部分所述,但如果我将所有情况减少到一个并加载第二个脚本(通常由远程脚本执行),在我自己的脚本中一切正常。
ajax
我不想使用像# coffee script
executeLater = ->
# this bit of code needs to run after the remote code has been executed.
console.log("yehaa!")
$.getScript("http://example.com/script-from-other-server.js")
.success( ->
$.ajax(
dataType: 'script',
cache: true,
# I do not know this url in production:
url: 'http://example.com/another-script-from-the-remote-server.js'
)
.success(executeLater)
)
个调用这样的构造,直到某个对象被定义为执行setTimout
方法。
executeLater()
回调使用executed
回调而不是executed
方法的success
回调是完美的。但是,到目前为止,我还没有找到这个回调。
ajax
有人知道在执行远程代码后如何执行# coffee script
executeLater = ->
# this bit of code needs to run after the remote code has been executed.
console.log("yehaa!")
$.ajax(
dataType: 'script',
url: 'http://example.com/script-from-other-server.js',
executed: executeLater # <---- I NEED A CALLBACK LIKE THIS
)
方法 ?谢谢!
正如 adeneo 在评论部分中指出的那样,JavaScript的same-origin policy可能就是问题所在。
我使用executeLater
或ajax
调用加载的脚本不允许从远程服务器加载和执行另一个脚本,以防止恶意脚本“回家”。
以下实验支持此功能:
getScript
根据this stackexchange answer,同源策略允许由html <html><head>
<script language="javascript" src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script language="javascript">
jQuery.getScript("http://example.com/script-from-other-server.js")
</script>
</head><body></body></html>
标记加载的远程脚本通过<script>
加载其他远程脚本。
ajax
问题仍然存在:使用ajax调用是否有好方法,或者,我必须通过插入{{1}来“证明”我“拥有此代码”标记到html文档?
答案 0 :(得分:2)
如果问题假定在请求的脚本完全执行之前调用了success
回调,那么真正的问题是,请求的脚本确实请求了另一个脚本,如问题中所述:
可能很重要:远程代码确实包含另一个
getScript(...)
调用。而且我必须等待这个代码也被执行。我不能简单地从我的代码加载第二个脚本,因为它的源是动态的(即取决于远程脚本的某些结果)。
当动态加载请求的脚本时,JavaScript的同源策略会阻止第二次getScript
调用。
如果有权访问html文件,可以添加脚本标记,远程脚本为src
。因此,一个&#34;证明&#34;那个人真的想加载这个远程脚本,javascript将执行远程getScript
调用。
<html><head>
...
<script language="javascript" src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script language="javascript" src="http://example.com/script-from-other-server.js"></script>
</head><body></body></html>
为了执行executeLater
代码,可以简单地使用ready
回调:
# coffee script
executeLater = ->
# this bit of code needs to run after the remote code has been executed.
console.log("yehaa!")
$(document).ready(executeLater)
不建议这样做,但可以。 有一个流行的堆栈溢出问题如何绕过同源策略:
Ways to circumvent the same-origin policy
如果除了同源策略之外,远程脚本真的需要很长时间才能执行,本地脚本必须等待它,可以使用Ahmed Nuaman的iframe解决方案:
答案 1 :(得分:0)
这有点讨厌,但您尝试使用iframe
吗?这个想法很简单:
action
和method
适合您正在尝试的请求。target
(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)设置为指向您网页上的iframe
,可以隐藏此iframe
。onload
的{{1}},加载iframe
后,即可执行您的代码。所以这是一个小例子(使用jQuery):
iframe