【问题标题】:JSONP Callback functionJSONP回调函数
【发布时间】:2019-12-07 10:05:33
【问题描述】:

我正在研究 JSONP 回调函数的概念。我阅读了一些关于此的文章,并希望很好地掌握 JSONP 的概念。

所以,我上传了一个 json 文件到服务器 - json file

这是我为检索数据而编写的 js 代码。调用是从 localhost 到 abhishekprakash.com。

var xhr;
var dataList;
xhr = new XMLHttpRequest();

xhr.open('GET', 'http://abhishekprakash.com/script/example.json?callback=func_callbk',  true);
xhr.send();

func_callback = function(data){
    alert(data.data.people[0].id);
}

xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
            console.log(dataList);
    }
};

这是我在控制台中得到的响应:

回调函数被调用,但它不包含 Json 数据。 我错过了什么?

感谢任何帮助。

谢谢

【问题讨论】:

  • 调用哪个回调? onreadystatechange 还是 func_callback?似乎您的响应是 JSON,而不是 JSONP,所以我看不到如何调用 func_callback
  • 该服务未返回正确的 JSONP 响应。是否应该明确支持 JSONP 调用?
  • 在控制台的 Params 选项卡中,我得到方法 func_callback
  • @deceze 由于调用是跨域的,它应该是 JSONP。这是 JSONP 的标准,对吧?
  • 要么设置 cors 标头,要么使用 jsonp。维基百科上有一篇关于同源策略的好文章,您完全误解了 JSON 和 JSONP 之间的区别。 JSON 是 "{\"message\":\"hello world\"}" JSONP 是回调({message:"hello world"})。 JSON 可以用 xhr 检索,而 jsonp 应该通过添加 srcipt 元素并将其 src 属性设置为 jsonp 来自的 url 来检索。然后在你的代码中你需要为回调提供一个函数

标签: javascript ajax jsonp


【解决方案1】:

该示例服务返回 JSON,而不是 JSONP。

JSONP 的要点是,由于同源策略安全限制,来自域 A 的 Javascript 无法向域 B 上的资源发出 GET 请求;换句话说,脚本无法跨域检索数据。

JSONP 通过使域 B 在跨域数据共享中显式协作来解决这个问题。来自域 A 的脚本指定了回调函数的名称,并将域 B 的 URL 嵌入到文档中,就好像它包含一个常规的外部 Javascript 文件一样。然后域 B 输出如下数据:

callbackFuncName({ data : foo, ... });

这意味着域 B 显式输出一个 Javascript sn-p,它使用数据调用指定的回调函数。

因此,除非域 B 在此方面明确合作,否则您不能简单地从中获取 JSONP 响应。

【讨论】:

  • +1。 Doh,完全阅读了 OP 说他们上传 json 文件的部分 =/
  • 那么,是不是我必须在json文件所在的域中进行一些调整,使其与需要数据的域协同工作?
  • @user 是的。您需要一个服务器端脚本来返回包装在指定回调函数中的 JSON 数据。另请参阅 Jack 的回答,了解如何从 Javascript 正确拨打电话。
  • +1 我喜欢你清楚地说另一端也需要合作发送正确的数据。不只是一端,它需要两者。
【解决方案2】:

XHR 受跨域规则约束;要使用 JSONP,您需要添加一个脚本元素:

function func_callbk()
{
    console.log(arguments);
}

var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'http://abhishekprakash.com/script/example.json?callback=func_callbk';
var h = document.getElementsByTagName('script')[0];
h.parentNode.insertBefore(s, h);

正如 Ian 在 cmets 中指出的,您的服务器的正确响应应该是这样的:

func_callbk('hello world')

更新

如果您希望在不使用 JSONP 的情况下进行这项工作(例如,如果响应应始终为 JSON),您需要按照this answer 中的说明查看 CORS。

【讨论】:

  • 正如 OP 所理解的那样,响应应该类似于 func_callbk(JSON_OBJECT);
  • @Ja͢ck 你能更直接地添加脚本元素吗?我选择了 github api 示例来演示他们的 jsonp 并修改了it slightly,它似乎可以工作。不需要你修改DOM来添加script标签吧?
  • @KedarMhaswade 如果脚本已经包含在文档中,则不需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-06
  • 1970-01-01
  • 2013-04-25
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多