Javascript 将附加参数传递给JSONP回调
对于我的一个项目,我需要使用JSONP对(远程)API进行多次调用,以处理API响应。所有调用都使用相同的回调函数。所有调用都是使用JavaScript在客户端动态生成的 问题如下:如何向该回调函数传递附加参数,以便告诉函数我使用的请求参数。因此,例如,在下面的示例中,我需要Javascript 将附加参数传递给JSONP回调,javascript,jsonp,Javascript,Jsonp,对于我的一个项目,我需要使用JSONP对(远程)API进行多次调用,以处理API响应。所有调用都使用相同的回调函数。所有调用都是使用JavaScript在客户端动态生成的 问题如下:如何向该回调函数传递附加参数,以便告诉函数我使用的请求参数。因此,例如,在下面的示例中,我需要myCallback函数来了解id=123。 有没有什么方法可以实现这一点,而不必为我的每个调用创建单独的回调函数?最好使用普通的JavaScript解决方案 编辑: 在第一次评论和回答之后,出现了以下几点: 我无法
myCallback
函数来了解id=123
。
有没有什么方法可以实现这一点,而不必为我的每个调用创建单独的回调函数?最好使用普通的JavaScript解决方案
编辑:
在第一次评论和回答之后,出现了以下几点:
- 我无法控制远程服务器。因此,向响应中添加参数不是一个选项
- 我同时启动了多个请求,所以任何存储参数的变量都不能解决问题
- 我知道,我可以动态创建多个回调并分配它们。但问题是,我是否能以某种方式避免这种情况。如果没有其他解决方案出现,这将是我的应急计划
// 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
});
既然我似乎不能评论,我必须写一个答案。我已经按照jfriend00对我的案例的说明进行了操作,但在回调中没有收到来自服务器的实际响应。我最后做的是:
var callbacks = {};
function doJsonCallWithExtraParams(url, id, renderCallBack) {
var safeId = id.replace(/[\.\-]/g, "_");
url = url + "?callback=callbacks." + safeId;
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", url);
callbacks[safeId] = function() {
delete callbacks[safeId];
var data = arguments[0];
var node = document.getElementById(id);
if (data && data.status == "200" && data.value) {
renderCallBack(data, node);
}
else {
data.value = "(error)";
renderCallBack(data, node);
}
document.body.removeChild(s);
};
document.body.appendChild(s);
}
本质上,我将goJSONP和getDataForUrl压缩为1个函数,该函数写入脚本标记(并在以后删除),并且不使用“unshift”函数,因为这似乎会从args数组中删除服务器的响应。因此,我只是提取数据并使用可用参数调用回调。这里的另一个区别是,我重复使用回调名称,我可能会使用计数器将其更改为完全唯一的名称
目前缺少的是超时处理。我可能会启动一个计时器并检查回调函数是否存在。如果它存在,它还没有删除自己,因此它是一个超时,我可以相应地采取行动。这已经有一年了,但我认为jfriend00走上了正确的轨道,尽管它比所有这些都简单-仍然使用闭包,只是在指定回调时添加参数: (‘optA’) (‘optB’) 然后使用闭包将其穿过:
function myFunc (opt) {
var myOpt = opt; // will be optA or optB
return function (data) {
if (opt == 'optA') {
// do something with the data
}
else if (opt == 'optB') {
// do something else with the data
}
}
}
有一个更简单的方法。
将参数附加到url的“?”之后。并在回调函数中访问它,如下所示
var url = "yourURL";
url += "?"+"yourparameter";
$.jsonp({
url: url,
cache: true,
callbackParameter: "callback",
callback: "cb",
success: onreceive,
error: function () {
console.log("data error");
}
});
以及回调函数,如下所示
function onreceive(response,temp,k){
var data = k.url.split("?");
alert(data[1]); //gives out your parameter
}
注意:如果URL中已有其他参数,则可以更好地在URL中追加参数。我在这里展示了一个快速脏的解决方案。您能让服务器返回id作为响应的一部分吗?服务器知道这一点,所以它可以为您将其放入响应代码中。您正在做需要做的事情。其余的由远程主机来识别您的参数。可能是的。。。。jQuery将使这变得非常简单,但如果您不想包含它,我可以理解。@jfriend00我无法控制远程服务器,因此没有任何更改代码动态生成JSONP调用?还是静态地包含在页面中?如果它是由代码动态生成的,则有更多的选项。这就是我心目中的后备计划。然而,这意味着创建(尽管是动态的)多个回调函数,这是我想要避免的。@Sirko-除非您能够保证一次只能有一个这种类型的JSONP请求,否则您必须执行类似的操作以将请求的状态与返回相匹配。根据定义,JSONP是相当愚蠢的。它所做的只是调用一个全局函数。而且,您已经拒绝让服务器为您解决此问题。因此,您必须将id存储在可访问的位置。如果要将正确的ID与正确的函数调用唯一地匹配,并且一次可以有多个函数调用,则每个函数调用必须是全局唯一的。@Sirko-如果一次只有一个JSONP调用(您可以保证这一点),然后将ID值存储在一个全局变量中,并从回调中检索它。这是一种脆弱的方法,因为当其他人不小心在同一时间执行两个JSONP调用时,代码中的细微变化很容易破坏它,而在此时解决问题将是一团混乱。仅供参考,我知道YUI做了一些事情
var url = "yourURL";
url += "?"+"yourparameter";
$.jsonp({
url: url,
cache: true,
callbackParameter: "callback",
callback: "cb",
success: onreceive,
error: function () {
console.log("data error");
}
});
function onreceive(response,temp,k){
var data = k.url.split("?");
alert(data[1]); //gives out your parameter
}