由于浏览器有同略策略,但是<script>标签的src可以跨域,利用这个"漏洞"搞事,具体做法是:
服务端地址(比如 http://api.xxx.com/jsonp.php?callback?callbackFunction
) 返回 json 数据的包装(故称为 jsonp,即json padding),形如 callback({"name":"Finley","gender":"Male"})
, 可以直接运行的 JS 脚本
浏览器提供一个回调函数(callbackFunction)来接收数据。
因为 script 标签只支持get
请求,故JSONP只能用GET请求
例子1 后台 PHP 代码,返回一段可 JS 运行的脚本,供前台调用
header('Content-type: application/json');
// 获取回调函数名
$jsoncallback = htmlspecialchars($_GET['jsoncallback']);
//json数据, 可以从数据库总获得
$json_data = '["customername1","customername2"]';
// 输出jsonp格式的数据
// callbackFunction(["customername1","customername2"]) 共前台js调用
echo $jsoncallback . "(" . $json_data . ")";
前台
<div id="divCustomers"></div>
<script type="text/javascript">
function callbackFunction(result, methodName) {
var html = '<ul>';
for (var i = 0; i < result.length; i++) {
html += '<li>' + result[i] + '</li>';
}
html += '</ul>';
document.getElementById('divCustomers').innerHTML = html;
}
</script>
<script src="http://localhost/finley/PHP/jsonp/jsonp.php?jsoncallback=callbackFunction"></script>
例子1中script标签是自己创建的,不方便,可以改为自动动态创建 参见一个开源库,代码非常简单 https://github.com/webmodules/jsonp/blob/master/index.js
1、ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装; 2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。 3、所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。 4、还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。
总而言之,jsonp不是ajax的一个特例,哪怕jquery等巨头把jsonp封装进了ajax,也不能改变这一点!
JSONP的总结: