我在使用jQuery的getJSON函数从API调用中提取特定元素时遇到问题。我正在尝试使用SunlightLab的congress API来提取有关立法者的具体信息。在下面的例子中,我试图拉一个立法者的网站:
$.getJSON("http://services.sunlightlabs.com/api/legislators.get.json?apikey=[api key]&lastname=Weiner&jsonp=?" , function(data) {
alert("hello from sunlight");
alert(data.response.legislator.website);
});
使用上面的代码,第一个警报显示,但第二个警报甚至不会发生。我知道getJSON应该在这个实例中使用JSONP,我想我已经正确设置,用“& jsonp =?”结束我的URL。
将我的getJSON函数中的URL放入Web浏览器中就可以得到:
?({“response”:{“立法者”: {“网站”: “http://weiner.house.gov/”,“传真”: “202-226-7253”,......等。
我有点被'?'抛出显示在此开头,但如果第一个警报显示,则请求必须成功...
答案 0 :(得分:2)
您正在使用的URL是将JSONP回调设置为等于?
,这意味着它注入了一个名为?
的JavaScript函数,其中包含一个JavaScript对象的参数。这是无效的。因此,请求成功,但您定义的包装函数未被调用(并且无效)。
您可以更改URL以使其jsonp=callback
(或其他一些处理函数名称),然后定义一个名为callback
的函数来处理期望该对象的参数。
在jQuery中(自动)触发JSONP支持的一种方法是将密钥切换为“回调”,以便向jQuery发出您正在进行JSONP调用的信号。即,callback=callback
。
编辑:正如Drackir指出的那样,jQuery在$.ajax
中提供了一个设置,允许它定义它自己的回调函数名称,但你需要通知它它的JSONP调用在dataType: 'jsonp'
来电中设置$.ajax
。
答案 1 :(得分:2)
问号是否存在是因为您指定了JSONP回调函数?在您的查询字符串中(即&jsonp=?
)。出于安全考虑(特别是same-origin policy),您无法向与您所在页面相同的域外的站点发出AJAX请求。为了解决这个问题,JSONP的工作原理是创建一个脚本标记,并将SRC设置为另一个站点上脚本的URL。这将加载外部JavaScript文件并运行任何代码。现在,为了将外部代码与JavaScript链接,外部API将使用要调用的函数的名称(&jsonp=functionnametocall
)。返回的JavaScript调用该函数并将其尝试作为JSON对象返回的数据作为第一个参数传递。
因此,当您去那里时看到问号的原因是因为您将问号传递给jsonp查询字符串参数。 jQuery会自动将诸如http://www.test.com/api/apikey=292929&callback=?
之类的URL中的问号转换为唯一命名的函数。这是由jQuery在后台处理的,所以你不必考虑它。
现在,我说,我不知道jQuery是否检测到回调参数的名称是否为callback=?
以外的其他名称。 $.getJSON()
然而,这是一个较长的简短形式:
$.ajax({
url: url,
dataType: 'json',
data: data,
success: callback
});
我建议您直接尝试使用$.ajax()
并将jsonp
设置设为"jsonp"
。这告诉$.ajax()
方法查询字符串参数被称为jsonp
而不是callback
。所以基本上这样:
$.ajax({
url: url,
dataType: 'json',
data: data,
success: callback,
jsonp:"jsonp"
});
答案 2 :(得分:0)
好的,好的,所以这是一个相当简单的修复,在@Drackir给出的示例中添加了一行。缺少的部分是ajax设置中的'cache:true'。最终的工作代码如下所示:
$.ajax({
url: 'http://services.sunlightlabs.com/api/legislators.get.json?apikey=[api key]7&lastname=Weiner',
dataType: 'jsonp',
cache: true,
jsonp: 'jsonp',
success: function(data) {
alert("hello from ajax") ;
alert(data.response.legislator.website);
}
});
我不确定为什么在这种情况下需要'cache:true'。谢谢你的帮助。