【发布时间】:2013-09-17 12:00:03
【问题描述】:
背景
我正在通过 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,then 代码在 在 when 块 执行 之前执行。
# 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)
)
要避免的事情
在定义某个对象并执行executeLater() 方法之前,我不愿意使用像几个setTimout 调用这样的结构。
我需要:executed 回调
最好使用一种executed 回调而不是ajax 方法的success 回调。但是,到目前为止,我还没有找到这个回调。
# 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
)
有什么线索吗?
有谁知道我如何在远程代码执行后执行executeLater 方法?谢谢!
编辑:同源政策
正如 adeneo 在 cmets 部分指出的那样,JavaScript 的 same-origin policy 可能是问题所在。
我使用ajax 或getScript 调用加载的脚本不允许从远程服务器加载和执行另一个脚本,以防止恶意脚本“回家”。
以下实验支持这一点:
这不起作用:
<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>
这行得通:
根据this stackexchange answer,同源策略允许通过html <script>标签加载的远程脚本通过ajax加载其他远程脚本。
<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>
问题仍然存在:有没有一种通过 ajax 调用的好方法,或者,我是否必须通过插入 <script> 标签来“证明”我“拥有此代码”在html文档中?
【问题讨论】:
-
这是一个格式很好的问题,但最大的问题仍然是,你确定 JavaScript 的同源策略不是问题吗?
-
@adeneo :我不确定,我怎样才能知道?我刚刚添加了“确实有效,但无法使用:ajax 两个脚本”部分。这能回答你的问题吗?
-
@adeneo :我看起来你是对的:SOP 可能是问题所在。请查看“编辑:同源政策”部分。你怎么看?
-
如您所说...您可能必须将脚本添加到您的 dom 元素以克服 SOP 问题...但仍然存在第二个问题...即在动态脚本加载完成
-
能否对第一个动态脚本元素进行一些更改
标签: jquery ajax callback cross-domain same-origin-policy