JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。

它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

如果对于callback参数如何使用还有些模糊的话,我们后面会有具体的实例来讲解。

首先,网页动态插入<script>元素,由它向跨源网址发出请求。

 <h1>绕过浏览器禁止跨域请求的方案之八——JSONP</h1>
<button id="bt1">请求数据</button>
<script src="jquery-1.11.3.js"></script>
<script>
//声明静态函数 —— 客户端不直接调用
function doRes(data){
console.log('开始处理服务器端返回的数据')
console.log(data);
} $('#bt1').click(function(){
//动态创建一个SCRIPT标签,添加到DOM
var s = document.createElement('script');
s.setAttribute('async', 'true'); //脚本异步执行
s.src = 'http://localhost/crossdomain/4.php?callback=doRes';
document.body.appendChild(s);
//OM树上追加了新的SCRIPT,浏览器就
//会立即请求该资源并执行服务器返回的JS })

上面代码通过动态添加<script>元素,向服务器http://localhost/crossdomain/4.php发出请求。

注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。

2.基于jquery的跨域

jquery发起跨域请求,有两种方法:

 (1)$.getJSON()

XHR非跨域请求:

$.getJSON('x.php', function(){})

SCRIPT实现JSONP请求

$.getJSON('跨域地址/x.php?callback=?', function(){})

 (2)$.ajax()

XHR非跨域请求:

$.ajax({....})

SCRIPT实现JSONP请求:

$.ajax({

url: '跨域地址/x.php',

dataType:'jsonp',

success: function(){ ... }

})

demo1如下:

 <h1>jQuery.getJSON与跨域请求</h1>
<button id="bt1">请求数据(非跨域)</button>
<button id="bt2">请求数据(跨域)</button>
<script src="jquery-1.11.3.js"></script>
<script>
$('#bt1').click(function(){
//XHR非跨域
$.getJSON('5-1.php', function(data){
console.log('1 处理服务器返回的数据')
console.log(data);
})
}); $('#bt2').click(function(){
//XHR跨域 —— 浏览器禁止
// $.getJSON('http://localhost/crossdomain/5-1.php?', function(data){
// console.log('2 处理服务器返回的数据')
// console.log(data);
// }) $.getJSON('http://localhost/crossdomain/5-2.php?callback=?',function(data){
console.log('3 处理服务器返回的数据')
console.log(data);
})
});

jquery在处理jsonp类型的ajax时(还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮

你生成回调函数并把数据取出来供success属性方法来调用。

在服务器端,代码如下:

 <?php
//header('Content-Type: application/json');
header('Content-Type: application/javascript');
sleep(10); //让当前解释器暂停执行10s
$cb = $_REQUEST['callback'];
$data = [
'ename'=>'Tom',
'age'=>20
];
echo $cb. '(' .json_encode($data) . ')';

demo2如下:

<h1>jQuery.ajax与跨域请求</h1>
<button id="bt1">请求数据(非跨域)</button>
<button id="bt2">请求数据(跨域)</button>
<script src="jquery-1.11.3.js"></script>
<script>
$('#bt1').click(function(){
//XHR非跨域
$.ajax({
url: '6-1.php',
success: function(){}
})
}); $('#bt2').click(function(){
$.ajax({
url: 'http://localhost/crossdomain/6-2.php',
dataType: 'jsonp', //指定响应消息的数据类型
success: function(data){
console.log('4 开始处理响应数据')
console.log(data); }
});
});

  

最新文章

  1. ListView 的使用
  2. 主成分分析PCA的前世今生
  3. 64位Windows下安装Redis教程
  4. 清北学堂模拟day4 传球接力
  5. 【COGS】894. 追查坏牛奶
  6. JSTL(JSP Standard Tag Library)读书笔记
  7. Android 开发性能优化之SparseArray(三)
  8. Android TextView中有图片有文字混合排列
  9. A transition animation compatible Library.
  10. MyBatis与Spring设置callSettersOnNulls
  11. Subsequences Summing to Sevens
  12. Java并发编程--线程池
  13. 谈谈Ext JS的组件——布局的使用方法续一
  14. hessian在ssh项目中的配置
  15. SVN状态说明
  16. windows环境下安装yaf框架
  17. 常用的 jQuery 事件
  18. 【函数】isinstance内建函数(小窗help)
  19. REST Framework 的分页
  20. GC知识随笔

热门文章

  1. 利用animate.css和es6制作文字向上滚动的效果
  2. pycharm每次新建项目都要重新安装一些第三方库的解决办法(转载防删)
  3. MySQL-Utilities:mysqldiff
  4. Eureka注册中心增加权限认证
  5. oracle数据导入/导出(2)
  6. LintCode_514 Paint Fence
  7. Java过滤器—Filter用法简介
  8. fastjson 对象和json互转
  9. oracle习题练习-表空间-用户-表-约束
  10. java-多线程的练习----妖,等待唤醒,代码重构,lock到condition