如何设置JSONP?

13
我需要在服务器端做些什么来允许其他人通过JSONP获取数据。同时,我在用户端需要做些什么呢?我希望使用JSONP作为XMLHttpRequest的替代方法。

由于同源策略的限制,这种方法在Firefox扩展程序中无法正常工作。因此,有人建议我使用JSON,但在网上搜索教程和指南后,我感到有些迷茫。

谢谢您的帮助!

3个回答

13
假设您的服务器正在运行PHP,您只需要添加“callback” GET请求。
<?php header('content-type: application/json; charset=utf-8');
$data = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5); 
echo $_GET['callback'] . '('.json_encode($data).')';

而在客户端(使用jQuery):

$.ajax({url: 'http://site.com/data.php', dataType:'jsonp'});

上面的 PHP 代码只是演示用的,请不要忘记 过滤 $_GET['callback']。

话虽如此,如果你的问题只涉及同源策略,你可能只需要从服务器端允许跨域请求,那么一切都应该能正常工作。


非常感谢!CORS解决方案帮我解决了问题。 - Jacques Blom
刚刚给这个回答点了踩,因为它假设使用的是 PHP,所以我更喜欢下面 T.J. Crowder 的回答。 - Steven2163712
@Steven2163712 如果你读了标题之外的内容,OP的问题实际上是CORS,与语言无关。虽然TJ的答案更通用(在我看来php已经足够通用了),但它并不能解决OP的问题。 - marko

7
在服务器端,您只需要设置一个Web资源(例如页面),该资源接受GET请求并使用JSON-P约定返回数据即可。JSON-P约定如下:
callback({"data": "here"});

......其中函数名(在该示例中为“callback”)通常取自查询字符串参数之一(按照惯例,参数为“callback”),数据是JSON文本(尽管技术上可以是任何在JavaScript对象文字中有效的内容,但使用JSON -P的惯例是限制您自己使用JSON中有效的内容)。例如,假设请求如下:

http://example.com/foo.php?callback=bar

这将调用页面foo.php(不必是PHP,可以是 任何动态服务器端系统),告诉它我们要调用的函数是“bar”。我们的响应将是:

bar({"data": "here"});

在客户端,你需要动态地向页面添加 `script` 元素,并且添加回调函数以触发 JSON-P 响应。通常情况下,你想要给函数一个随机的名称,并在使用完毕后将其删除。
这里有一个完整的示例作为 Stack Overflow 上另一个问题的答案。你可能需要稍微调整一下才能在 Firefox 插件中使用,但概念是相同的。

1

JSONP 是带有包装器的 JSON,因此您可以通过动态插入新的 <script> 标签并将其指向另一个服务器的 src,来模拟对另一个服务器的 Ajax 请求。包装器本质上使 jsonp 返回的内容成为一个有效的 JavaScript 函数调用,从而可以执行提取其中的标准 JSON 数据。

通常,在不安全的“仅供演示”的版本中,您会有以下内容:

function unwrap_jsonp(data) {
    eval(data);
}

远程服务器将返回以下文字字面量:
unwrap_json("{'this':'is','sparta':'!'}");

请注意,这是字面上的Javascript纯文本代码,它会执行并将嵌入的JSON字符串“解包”回到本地javascript数据结构中。
大多数JSONP服务允许通过查询字符串指定一个额外的参数来命名处理程序函数,您可以将响应包装在其中,例如。
http://example.com/getjsonp.php?callback=unwrap_json

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接