一、JSONP的诞生

  • 首先,因为ajax无法跨域,然后开发者就有所思考

  • 其次,开发者发现, <script>标签的src属性是可以跨域的 
    把跨域服务器写成 调用本地的函数 ,回调数据回来不就好了?

  • json刚好被js支持(object)

  • 调用跨域服务器上动态生成的js格式文件(不管是什么类型的地址,最终生成的返回值都是一段js代码)

  • 这种获取远程数据的方式看起来非常像ajax,但其实并不一样 
    便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP。

  • 传递一个callback参数给跨域服务端,然后跨域服务端返回数据时会将这个callback参数作为函数名来包裹住json数据即可。

二、老板,来一斤栗子。

【栗子一】
跨域服务器

文件:remote.js 
代码:

alert('我是远程文件');

本地

<script type="text/javascript" src="跨域服务器/remote.js"></script>

这边做的就是直接引入一个js,页面将会弹出一个提示窗体,显示 我是远程文件。

【栗子二】
跨域服务器

文件:remote.js 
代码:

localHandler({"result":"我是远程js带来的数据"});

本地

<script type="text/javascript">

   var localHandler = function(data){

       alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);

   };

</script>

<script type="text/javascript" src="跨域服务器/remote.js"></script>

这边做的是 
1、本地定义一个函数 
2、引入一个js 
3、被引入的js里面,调用这个函数

页面将会弹出一个提示窗体。显示本地函数被跨域的远程js调用成功,并且还接收到了 我是远程js带来的数据。 
新问题出现了:让远程js知道它应该调用的本地函数叫什么名字呢?毕竟是jsonp的服务者都要面对很多服务对象,而这些服务对象各自的本地函数都不相同啊?

【栗子三】

跨域服务端提供的js脚本动态生成,这样调用者可以传一个参数过去告诉跨域服务端“我想要一段调用XXX函数的js代码,请你返回给我”,于是跨域服务器就可以按照客户端的需求来生成js脚本并响应了。

跨域服务器

文件:flightResult.php 
代码:

flightHandler({

   "code":"CA1998",

   "price": 1780,

   "tickets": 5

});

本地

<script type="text/javascript">

   // 得到航班信息查询结果后的回调函数

   var flightHandler = function(data){

       alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');

   };

   // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)

   var url = "跨域服务器/flightResult.php?code=CA1998&callback=flightHandler";

   // 创建script标签,设置其属性

   var script = document.createElement('script');

   script.setAttribute('src', url);

   // 把script标签加入head,此时调用开始

   document.getElementsByTagName('head')[0].appendChild(script);

</script>

这次我们做的是 
1、动态创建脚本 
2、url中传递了一个code参数,服务器去做查询CA1998次航班的信息,callback参数告诉服务器,我的本地回调函数叫做flightHandler 
3、跨域服务端调用这个函数flightHandler 页面将会弹出一个提示窗体。把票价、余票以及张数给传递回来了。

三、那么服务器到底做了什么呢? 说到底,就是拼接字符串。

// 数据

$data = [

   "name":"anonymous66",

   "age":"18",

   "like":"jianshu"

];

// 接收callback函数名称

$callback = $_GET['callback'];

// 输出

echo $callback . "(" . json_encode($data) . ")";

四、与AJAX的区别是什么?

ajax和jsonp本质上是不同的东西。 
ajax的核心是通过XmlHttpRequest获取非本页内容 
jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。

170109、JSONP是什么的更多相关文章

  1. 实例操作JSONP原理

    絮语:按这个步骤走,你就会明白JSONP是什么鬼. 1.工程目录: ng-mywork demo.html test.js 2.nginx的server配置 server { listen ; ser ...

  2. angular2系列教程(九)Jsonp、URLSearchParams、中断选择数据流

    大家好,今天我们要讲的是http模块的第二部分,主要学习ng2中Jsonp.URLSearchParams.observable中断选择数据流的用法. 例子

  3. 疯狂的JSONP

    何为跨域?何为JSONP?JSONP技术能实现什么?是否有必要使用JSONP技术? 跨域 就是由于JavaScript同源策略的限制,使得a.com域名下的js无法操作b.com或c.a.com域名下 ...

  4. 通过扩展让ASP.NET Web API支持JSONP

    同源策略(Same Origin Policy)的存在导致了"源"自A的脚本只能操作"同源"页面的DOM,"跨源"操作来源于B的页面将会被拒 ...

  5. 跨域的jsonP

    1.出现原因:因为web中的同源策略(域名,协议,端口号)限制了跨域访问.   2.区别于json (个人理解)json是数据交换格式,jsonp是数据通信中的交互方式   3.jsonp的get与p ...

  6. ASP.NET Web API 配置 JSONP

    之前的一篇博文:jsonp跨域+ashx(示例) 1. 安装 Jsonp 程序集: PM> Install-Package WebApiContrib.Formatting.Jsonp PM&g ...

  7. 原生JS封装Ajax插件(同域&&jsonp跨域)

    抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...

  8. 跨域之jsonp

    我们都知道使用<script>标签可以引入外部的JS文件,即使这个JS文件来自于其他的网站,比如我们引用存放在网络服务器上的jQuery框架.在这个过程中,我们已经实现跨域访问.像< ...

  9. 由浅入深学习ajax跨域(JSONP)问题

    什么是跨域?说直白点就是获取别人网站上的内容.但这么说貌似又有点混淆,因为通常我们用ajax+php就可以获取别人网站的内容,来看下面这个例子. 来看看跨域的例子,jquery+ajax是不能跨域请求 ...

随机推荐

  1. Android(java)学习笔记259:JNI之NDK开发步骤

    1. NDK开发步骤(回忆一下HelloWorld案例): (1)创建工程 (2)定义native方法 (3)创建jni文件夹 (4)创建c源文件放到jni文件夹 (5)拷贝jni.h头文件到jni目 ...

  2. 关于飞控下载时候出现avrdude: stk500_getsync(): not in sync: resp=0x00错误的解决方法

    avrdude: stk500_getsync(): not in sync: resp=0x00该问题表述为串口通信失败 经过分析,出现这种情况的原因大致有:1.arduino在IDE下载过程中没有 ...

  3. 安装 vs2005, vs2008 报错

    最近重新装了系统之后,在安装 vs2005, vs2008 到如下类似的错误,苦苦两天没有解决.不要问为什么是 vs2005,vs2008, 因为原有的项目就是老版本. 无意间在网上看到一句话,大意是 ...

  4. Examples_08_03

    访问本地程序.http://192.168.1.103/preg_match/test.php,如果换成localhost或者127.0.0.1,则会导致无法访问. http://blog.csdn. ...

  5. (转,感谢原作者!)既然选择了Linux,有何必在乎这些——Linux wine国服LOL英雄联盟,完美运行!!

    Linux下玩国服LOL,国服哦.网络上随处都可以搜到wine美服LOL的教程,但腾讯运营的国服客户端跟美服原版相差比较大,按照美服的方式不能搞起国服LOL,由于宿舍文化,这几天我专注于wine一个国 ...

  6. SQL Server 2008 R2 的版本和组件

    SQL Server 2008 R2 的版本和组件 SQL Server 2008 R2   其他版本 SQL Server 2008 SQL Server 2005 SQL Server 2012 ...

  7. asp.net能不托管吗?

    弱弱地问一句,整个部署在IIS中的asp.net项目能不托管吗? 或者说有没有用纯粹的非托管语言(比方说C语言)写的非托管asp.net项目?

  8. wm_char

    用于接收键盘输入的消息 int CXuexi2View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateS ...

  9. jquery 获取 outerHtml 包含当前节点本身的代码

    在开发过程中,jQuery.html() 是获取当前节点下的html代码,并不包含当前节点本身的代码,然后我们有时候确需要,找遍jQuery api文档也没有任何方法可以拿到. 看到有的人通过pare ...

  10. xml代码

    修改和删除: <?php$doc=new DOMDocument();$doc->load("php.xml");$root=$doc->documentElem ...