1.什么是JSONP ?

  JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

  JSON 数据是一种能很方便通过 JavaScript 解析的结构化数据。如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用 jsonp 类型。

  使用jsonp 类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的 URL 后面。服务器端应当在 JSON 数据前加上回调函数名,以便完成一个有效的 JSONP 请求。如果要指定回调函数的参数名来取代默认的 callback,可以通过设置 $.ajax() 的 jsonp 参数。

注意:

  • JSONP 是 JSON 格式的扩展。它要求一些服务器端的代码来检测并处理查询字符串参数。
  • AJAX和JSONP在本质上是完全不同的东西。AJAX的核心是通过XmlHttpRequest获取数据,而JSONP的核心是动态添加<script>标签来调用服务器提供的js脚本。

2.为什么要用JSONP?

  由于浏览器的“同源策略(SOP:Same OriginPolicy)”,浏览器限制脚本程序只能和同协议、同域名、同端口的脚本进行交互,这包括共享和传递变量等。cookie的传递也是遵从同样策略。这就造成一些涉及到多个服务器的应用在整合时一些麻烦。跨域访问的问题造成A站点无法访问B站点的数据。

  尽管浏览器不允许页面中的脚本程序跨域读取数据,但却允许HTML引用跨域的资源,如图片,CSS和脚本程序。对于脚本程序的引用比较特殊,它被浏览器解析以后,就和本地的脚本程序别无二致且可立即进行解释并执行。

  如下引用:<script typet="text/javascript" src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>是有效的。总结发现,拥有“src”属性的标签有跨域的能力,如script、img、iframe等。

  由于站外脚本的引用是通过script标签来实现的,而脚本程序又可通过DOM的方式可以对HTML页面的所有标签进行控制(包括动态的创建script标签),这就可以实现通过调用站外程序对本地资源进行更改了。另外,通过<script>标签的使用,就可从服务端直接返回可执行的JavaScript函数调用或者JSON数据。

3.JSONP实现流程

  首先在客户端(A站点)注册一个callback事件,然后把callback事件的名字作为参数传给服务器(B站点)。此时,服务器(B站点)会生成 JSON数据,同时生成一个funtion,该funtion就是客户端(A站点)的callback事件。

  然后,将JSON数据直接以参数的形式,放置到function中,这样就生成了一段 js 语法的文档,返回给客户端。

  最后,在客户端浏览器中解析script标签,并执行从服务器(B站点)返回的function,此时服务器(B站点)返回的json数据作为参数,传入到了客户端预先定义好的回调函数里(动态执行回调函数)。 
  可以说jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的。

3.怎样使用JSONP

  从http://A.com/index.html页面访问http://B.com/services.php的数据

示例1:

<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">

  //在客户端注册callback事件
   function jsonpCallback(result) {
    console.log(result.msg);   

  }
  var Script=document.createElement("script");//创建一个script标签
  Script.type="text/javascript";

  //提供JSONP服务的地址
   Script.src="http://B.com/services.php?callback=jsonpCallback";

  //把script标签放到head里,此时调用开始
   document.getElementsByTagName("head")[0].appendChild(Script);
</script>

示例2:需要传递参数的写法

<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<script type="text/javascript">
  function jsonpCallback(result) {
      console.log(result.msg);
   }
</script>
<script type="text/javascript" src="http://B.com/services.php?参数名=参数值&&callback=jsonpCallback"></script>

  当GET请求从http://B.com/services.php返回时,可以返回一段JavaScript代码,这段代码会自动执行,可以用来负责调用http://A.com/index.html页面中的一个callback函数。

注意:

  • 调用了回调函数的script标签必须写在回调函数的下面。
  • jsonCallback是获取跨域服务器上的JSON数据后的客户端的回调函数。
  • http://a.com/services.php?callback=jsonpCallback是获取跨域服务器JSON数据的接口,参数为回调函数的名字。
  • 不管是什么类型的地址,最后生成的返回值都是一段javascript代码。
  • 回调的数据格式为:jsonpCallback({ msg:'hello JSONP'} )。
  • 以上代码是写在客户端js文件里的。

4.jQuery怎样实现JSONP调用?

  以上方法使用JavaScript原生方法实现的。从jQuery1.2版本开始,jQuery拥有对JSONP回调的本地支持。如果指定了JSONP回调,就可以加载另一个域的JSON数据,回调的语法为 url?callback=? 。jQuery自动将  callback=?  的  ?  替换为要调用的函数名。

示例1:$.ajax()方法

<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript">   

  $.ajax({

    type:'get',    

    url:"http://a.com/services.php?参数名=参数值",

    dataType:'jsonp',

    jsonp:'callback',  //传递给请求处理程序或页面的,用以获得JSONP回调函数名的参数名(一般默认为:callback)

    jsonpCallback:'jsonpCallback',

    timeout:2000,

     success:function(result){ 

      console.log(result.msg); 

       } 

  });

</script>

注意:

  • jsonp:'callback'   传递给请求处理程序或页面的,用以获得JSONP回调函数名的参数名(一般默认为:callback)
  • jsonpCallback:'jsonpCallback'   自定义的JSONP回调函数名称,默认为jQuery自动生成的随机函数名,也可以写成  ?  ,jQuery会自动为你处理函数
  • jquery在处理jsonp类型的ajax时,会自动生成回调函数并把数据取出来供success属性方法来调用

示例2:使用$.get()方法

语法:$.get(URL,data,function(data,status,xhr),dataType)

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
  $.get('http://B.com/services.php?callback=?', {name:   encodeURIComponent('tester')}, function (json) {

    console.log(result.msg); }, 'jsonp');
</script>

encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。

示例3:使用$.getJSON()方法

$.getJSON(url,data,success(data,status,xhr))

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
  $.getJSON("http://B.com/services.php?callback=?",
    function(result) {
      console.log(result.msg);

  });
</script>

5.JSONP的缺陷

  JSONP没有错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。而且JSONP存在一定的安全隐患。

JSONP 详解的更多相关文章

  1. [转]jsonp详解

    jsonp详解 json相信大家都用的多,jsonp我就一直没有机会用到,但也经常看到,只知道是“用来跨域的”,一直不知道具体是个什么东西.今天总算搞明白了.下面一步步来搞清楚jsonp是个什么玩意. ...

  2. ajax、反向ajax、jsonp详解

    ajax详解 什么是ajax 其实ajax已经属于老技术了,现在几乎没人不会用了,在这里主要是把底层的东西给大家分享一下,以备应对装逼的面试官. ajax即“Asynchronous Javascri ...

  3. JSONP详解

    0.关于JSONP 什么的JSONP JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料.另一个解决这个问题的新方法是跨来源资源共享. ...

  4. 【转】jsonp详解

    原文地址:http://www.cnblogs.com/yuzhongwusan/archive/2012/12/11/2812849.html json相信大家都用的多,jsonp我就一直没有机会用 ...

  5. 防止跨域(jsonp详解)

    详见:http://www.cnblogs.com/lemontea/archive/2012/12/11/2812268.html $("#getJsonpByJquery"). ...

  6. JSON和JSONP详解

    什么是JSON JSON是一种基于文本的数据交换方式,或者叫做数据描述格式,你是否该选用他首先肯定要关注它所拥有的优点. JSON的优点: 1.基于纯文本,跨平台传递极其简单: 2.Javascrip ...

  7. 浏览器跨域问题(jsonp)——jsonp详解

    json相信大家都用的多,jsonp我就一直没有机会用到,但也经常看到,只知道是“用来跨域的”,一直不知道具体是个什么东西.今天总算搞明白了.下面一步步来搞清楚jsonp是个什么玩意. 同源策略 首先 ...

  8. [转载]jsonp详解

    http://www.cnblogs.com/lemontea/archive/2012/12/11/2812268.html json相信大家都用的多,jsonp我就一直没有机会用到,但也经常看到, ...

  9. json与jsonp详解

     前言: 说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域 ...

随机推荐

  1. 【BZOJ1877】晨跑(费用流)

    [BZOJ1877]晨跑(费用流) 题面 Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他 坚持下来的只有晨跑. 现在 ...

  2. 【Luogu1373】小a和uim之大逃离(动态规划)

    [Luogu1373]小a和uim之大逃离(动态规划) 题面 题目背景 小a和uim来到雨林中探险.突然一阵北风吹来,一片乌云从北部天边急涌过来,还伴着一道道闪电,一阵阵雷声.刹那间,狂风大作,乌云布 ...

  3. [BZOJ1001] [Beijing2006] 狼抓兔子 (最短路)

    Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个 ...

  4. Pycharm头部注释添加

    1.第一步 2.第二步 搜索框输入:File and Code Templates 然后右边找到 Python Script 3.第三步 将下面内容复制到图中红框内,然后点击OK #!/usr/bin ...

  5. sshpass的使用方法

    author:headsen  chen date : 2017-11-29  15:46:39 notice:created  by  headsen chen himself   and not ...

  6. shell脚本中的整数测试

    shell脚本中的整数测试 author:headsen chen      2017-10-17   13:58:12 个人原创,转载请注明作者,出处,否则依法追究法律责任 1,test用法:tes ...

  7. Redis搭建多台哨兵

    搭建多台哨兵 完成spring管理多台哨兵 学习redis如何数据持久化如何管理内存 Redis集群搭建 集群测试 Spring管理集群 2 搭建多台哨兵 2.1 搭建步骤 2.1.1 修改6379哨 ...

  8. ER图

    E-R图也称实体-联系图(Entity Relationship Diagram), 提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. 它是描述现实世界概念结构模型的有效方法.是表示 ...

  9. NGUI_slider

    十一.进度条UISlider 1.一般按以下规律使用进度条; 如果某一钟值,他有最大值,需要表达当前的值得占比,则可以使用不可拖动的进度条 如果某一值,他有最大值,需要玩家记性滑动设置,则可以使用可拖 ...

  10. Java基础知识回顾之二 ----- 修饰符和String

    前言 在上一篇中,回顾了Java的基本数据类型 ,这篇就来回顾下Java中的一些修饰符以及String. 修饰符介绍 Java修饰符主要分为两类: 访问修饰符 非访问修饰符 其中访问修饰符主要包括 p ...