JSONP是JSON with padding(填充式JSON或参数式JSON)的简写,是应用JSON的一种新方法,常用于服务器与客户端跨源通信,在后来的Web服务中非常流行。本文将详细介绍JSONP

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

  当通过<script>元素调用数据时,响应内容必须用javascript函数名和圆括号包裹起来。而不是发送这样一段JSON数据,这就是JSONP中P的意义所在

[1, 2, {"buckle": "my shoe"}]

  JSONP看起来与JSON差不多,只不过是被包含在函数调用中的JSON,它会发送这样一个包裹后的JSON响应:

handleResponse([l, 2, {"buckle": "my shoe"}])

  

 包裹后的响应会成为<script>元素的内容,它先判断JSON编码后的数据,然后把它传递给handleResponse()函数

  在实践中,支持JSONP的服务不会强制指定客户端必须实现的回调函数名称,比如handleResponse。相反,它们使用査询参数的值,允许客户端指定一个函数名,然后使用函数名去填充响应。许多支持JSONP的服务都能分辨出这个参数名。另一个常见的参数名称是callback,为了让使用到的服务支持类似特殊的需求,就需要在代码上做一些修改了

  JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的JSON数据

http://freegeoip.net/json/?callback=handleResponse

  

这个URL是在请求一个JSONP地理定位服务。通过査询字符串来指定JSONP服务的回调参数是很常见的,就像上面的URL所示,这里指定的回调函数的名字叫handleResponse()

  JSONP是通过动态<script>元素来使用的,使用时可以为src属性指定一个跨域URL。这里的<script>元素与<img>元素类似,都有能力不受限制地从其他域加载资源。因为JSONP是有效的javascript代码,所以在请求完成后,即在JSONP响应加载到页面中以后,就会立即执行

function handleResponse(response){alert ("You're at IP address " + response.ip + ", which is in " + response.city + ", "+ response.region_name);
}
var script = document.createElement("script");
script.src = "http://freegeoip.net/json/?callback=handLeResponse"; document.body.insertBefore(script, document.body.firstChild);

  

 JSONP之所以在开发人员中极为流行,主要原因是它非常简单易用,老式浏览器全部支持,服务器改造非常小。与图像Ping相比,它的优点在于能够直接访问响应文本,支持在浏览器与服务器之间双向通信

  使用<script>元素进行Ajax传输,不受同源策略的影响,因此可以使用它们从其他的服务器请求数据;而且,包含JSON编码数据的响应体会自动解码(即执行)

  不过,JSONP也有两点不足:首先,JSONP是从其他域中加载代码执行。如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时除了完全放弃JSONP调用之外,没有办法追究。因此在使用不是自己运维的Web服务时,一定得保证它安全可靠;其次,要确定JSONP请求是否失败并不容易。虽然HTML5给<script>元素新增了一个onerror事件处理程序,但目前还没有得到任何浏览器支持。为此,开发人员不得不使用计时器检测指定时间内是否接收到了响应。但就算这样也不能尽如人意,毕竟不是每个用户上网的速度和带宽都一样

简易示例

【前端】

<button id="btn">获取信息</button>
<img id="img" height="16" style="display:none" src="https://img-blog.csdnimg.cn/2022010619021233770.gif" alt="loading">
<div id="result"></div>
<script>
var add = (function(){var counter = 0;return function(){return ++counter;}
})();
function loadScript(url){loadScript.mark = 'load';var script = document.createElement("script");script.type = "text/javascript";script.src = url;script.onload = function(){img.style.display = 'none';btn.removeAttribute('disabled');}document.body.appendChild(script);
}
function test(data){var sum = add() - 1;if(sum < data.length ){result.innerHTML += data[sum];    }
}
btn.onclick = function(){img.style.display = 'inline-block';btn.setAttribute('disabled','');loadScript('https://www.webhuochai.com/test/getData.php?callback=test');
}
</script>

  

【后端】

<?php
function test_input($data) {$data = trim($data);$data = stripslashes($data);$data = htmlspecialchars($data);return $data;
}
$arr = [1,2,3,4,5];
echo test_input($_GET['callback']) ."(" .json_encode($arr) .");";
?>

  

百度搜索框

  百度搜索框就是使用了JSONP的技术,在百度搜索的URL中,有用的查询如下

https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=123&&cb=a

  

结果为:

a({q:"123",p:false,s:["12306","12306铁路客户服务中心","12308汽车订票官网","12306火车票网上订票官网","12333","12315","12345","12333社保查询网","123网址之家","12366"]});

  

 所以,wd为关键词,cb用来JSONP的函数名。在获取的数据中,s为以关键词开始的数据组成的数据

  百度搜索的关键URL如下

https://www.baidu.com/s?wd=a

  

wd为关键词,当wd=a时,将打开关键词为a的网页

<style>
body{margin: 0;}
ul{margin: 0;padding: 0;list-style: none;}
a{color:inherit;text-decoration: none;}
input{padding: 0;border: 0;}
.box{width: 340px;height: 38px;border: 2px solid gray;}
.con{overflow: hidden;}
.input{float: left;width: 300px;height: 38px;}
.search{width: 38px;height: 38px;float: right;background: url('http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/search.png') 0 -38px;}
.list{position: absolute;width: 298px;border: 1px solid #e6e8e9; overflow: hidden;}
.in{line-height: 30px;border-bottom: 1px solid lightblue;cursor:pointer;text-indent: 1em;}
.list .in:last-child{margin-bottom: -1px;}
.in:hover{background-color: #f9f9f9;}
</style><div class="box" id="box"><div class="con"><input class="input" id="search"><a target="_blank" id="btn" href="javascript:;" class="search"></a></div><ul class="list" id="list"></ul>
</div>
<script>
function loadScript(url){loadScript.mark = 'load';var script = document.createElement("script");script.type = "text/javascript";script.src = url;document.body.appendChild(script);
}
function callback(data){if(data){var arr = data.s;var html = '';for(var i = 0,len = arr.length; i < len; i++){html+= "<li class='in'><a href='https://www.baidu.com/s?wd="+ arr[i]+"' target='_blank' style='display:block'>" + arr[i]+ "</a></li>"}list.innerHTML = html;        }
}
search.onkeyup = function(e){e = e || event;if(e.keyCode == '13'){window.open('https://www.baidu.com/s?wd=' + this.value);}if(this.value){if(search.data != this.value){btn.setAttribute('href','https://www.baidu.com/s?wd=' + this.value);var that = this;loadScript("https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=" + that.value + "&&cb=callback");}}else{list.innerHTML = '';}search.data = this.value;
}
search.onclick = function(e){e = e || event;list.style.display = 'block';if(e.stopPropagation){e.stopPropagation();}else{e.cancelBubble = true;}
}
document.onclick = function(){list.style.display = 'none';
}
</script>

  

jsonp: js跨域相关推荐

  1. js跨域请求方式 ---- JSONP原理解析

    这篇文章主要介绍了js跨域请求的5中解决方式的相关资料,需要的朋友可以参考下 跨域请求数据解决方案主要有如下解决方法: 1 2 3 4 5 JSONP方式 表单POST方式 服务器代理 Html5的X ...

  2. 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  3. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  4. js跨域交互(jQuery+php)之jsonp使用心得

    jsonp是什么? 说到jsonp,你可能最先想到JSON:它还真和JSON有关系: JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏 ...

  5. 使用 JSONP 实现跨域通信,第 2 部分: 使用 JSONP、jQuery 和 Yahoo! 查询语言构建 mashup...

    使用 JSONP 实现跨域通信,第 2 部分: 使用 JSONP.jQuery 和 Yahoo! 查询语言构建 mashup 使用 JSONP 实现跨域通信,第 2 部分: 使用 JSONP.jQue ...

  6. Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持

    Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持 1.设置 document.domain为一致  推荐1 2.Apache 反向代理 推荐1 3. ...

  7. window.opener方法的使用 js跨域

    2019独角兽企业重金招聘Python工程师标准>>> 最近公司网站登陆加入了第三方登陆.可以用QQ直接登陆到我们网站,在login页面A中点QQ登陆时,调用了一个window.op ...

  8. 5种处理js跨域问题方法汇总(转载)

    1.JSONP跨域GET请求 ajax请求,dataType为jsonp.这种形式需要请求在服务端调整为返回callback([json-object])的形式.如果服务端返回的是普通json对象.那 ...

  9. firefox如何载入json文件_如何去解决JS跨域问题 怎么能学好Web前端开发

    如何去解决JS跨域问题?怎么能学好Web前端开发?JavaScript跨域是指通过JS在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过JS获取页面中不同域的框架中(if ...

最新文章

  1. python 二维list取列
  2. 微软的漏洞攻击与防御
  3. docker安装mysql及相关配置、运行细节和常见报错解决方案
  4. 普通的101键盘在Mac上的键位对应
  5. mysql savepoint 什么意思_关于MySQL中savepoint语句使用时所出现的错误
  6. 据说 99% 的人不知道 vue-devtools 还能直接打开对应组件文件?本文原理揭秘
  7. Codeforces Round #732 (Div. 1Div. 2)
  8. 3、oracle数据库的语法基础
  9. minheight能继承吗_民法典亮点盘点 | 侄子能继承叔叔的遗产吗?
  10. 酷炫星空公告维护页源码
  11. 绿盟漏洞扫描_二十周年专题|绿盟极光,用专注惊艳了时光
  12. Spring Boot : Whitelabel Error Page解决方案
  13. no target device found怎么解决_关于移动端开发 1px 线的一些理解和解决办法
  14. 日请求从百万到八亿的技术历程
  15. android彻底退出应用_Android完全退出应用程序的方法
  16. 3S基础知识:VB中利用MapX创建用户定制工具
  17. 2021年最新程序员培训机构排名,学习前避坑必看
  18. 计算机技术比武优秀获奖感言,教学大赛获奖感言4篇
  19. 80端口和443端口的作用
  20. Spring 专业认证考试学习指南

热门文章

  1. EXSi6.7升级7.03失败记录
  2. 打游戏的蓝牙耳机推荐哪一款?打游戏比较好的蓝牙耳机推荐
  3. 物联卡中心:快手上买物联卡是真的吗?小心陷入“骗局”!
  4. 在Unity中如何制作动画
  5. 水溶性近红外Ⅱ区荧光Ag2Te量子点的合成,近红外二区量子点荧光染料激发1000nm以上
  6. kylin focal fossa ubuntu20.04安装 cuda cudnn lib
  7. 怎么删除pdf中的文字
  8. Springboot Mybatis使用pageHelper实现分页查询
  9. linux中groupadd命令详解,Linux命令之groupadd详解
  10. Ceph BlueStore Allocator