对于我的一个项目,我需要使用 JSONP 对(远程)API 进行多次调用以处理 API 响应。所有调用都使用相同的回调函数。所有调用都是在客户端使用 JavaScript 动态生成的。
问题如下:如何将附加参数传递给该回调函数,以便将我使用的请求参数告知该函数。因此,例如,在下面的示例中,我需要 myCallback
函数来了解 id=123
。
<script src="http://remote.host.com/api?id=123&jsonp=myCallback"></script>
有什么方法可以实现这一点而不必为我的每个调用创建一个单独的回调函数?首选 vanilla JavaScript 解决方案。
编辑:
在第一次评论和回答之后,出现了以下几点:
- 我对远程服务器没有任何控制权。因此,将参数添加到响应中不是一种选择。
- 我同时启动了多个请求,因此任何用于存储我的参数的变量都无法解决问题。
- 我知道,我可以即时创建多个回调并分配它们。但问题是,我是否能以某种方式避免这种情况。如果没有其他解决方案出现,这将是我的后备计划。
最佳答案
您的选择如下:
- 让服务器将 ID 放入响应中。这是最干净的,但通常您无法更改服务器代码。
- 如果您可以保证一次涉及 ID inflight 的 JSONP 调用不会超过一个,那么您可以将 ID 值填充到一个全局变量中,然后在调用回调时从全局变量中获取 id 值.这很简单,但也很脆弱,因为如果同时处理多个涉及 ID 的 JSONP 调用,它们将相互踩踏,导致无法正常工作。
- 为每个 JSONP 调用生成一个唯一的函数名称,并使用与该函数名称关联的函数闭包将 id 连接到回调。
这是第三个选项的示例。
您可以使用闭包来为您跟踪变量,但是由于您可以同时进行多个 JSON 调用,因此您必须使用动态生成的全局可访问函数名称,该名称对于每个连续的 JSONP 都是唯一的称呼。它可以像这样工作:
假设您为 JSONP 生成标签的函数是这样的(您可以替换您现在使用的任何内容):
function doJSONP(url, callbackFuncName) {
var fullURL = url + "&" + callbackFuncName;
// generate the script tag here
}
然后,您可以在它之外使用另一个函数来执行此操作:
// global var
var jsonpCallbacks = {cntr: 0};
function getDataForId(url, id, fn) {
// create a globally unique function name
var name = "fn" + jsonpCallbacks.cntr++;
// put that function in a globally accessible place for JSONP to call
jsonpCallbacks[name] = function() {
// upon success, remove the name
delete jsonpCallbacks[name];
// now call the desired callback internally and pass it the id
var args = Array.prototype.slice.call(arguments);
args.unshift(id);
fn.apply(this, args);
}
doJSONP(url, "jsonpCallbacks." + name);
}
您的主代码将调用 getDataForId()
并且传递给它的回调将像这样传递 id 值,后跟 JSONP 在函数上的任何其他参数:
getDataForId(123, "http://remote.host.com/api?id=123", function(id, /* other args here*/) {
// you can process the returned data here with id available as the argument
});
关于javascript - 将附加参数传递给 JSONP 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9570768/