http://www.g7blogs.com/?p=821

作为一枚前端,提起jsonp大家都不会陌生。特别是在我们组内的业务中,和服务器端交互的数据几乎都是采用这种形式。但假如要让你用原生的JS写出XHR请求来构造JSONP,估计都要跪了吧。因为我们都习惯把jQuery当成了JS的一部分了,就好比平时都是坐飞机到帝都的,你突然说让我骑个单车上北京。不是说不行,只是平时骄奢惯了,适应不了原生态。所以这篇东西要说的并不是那些Google随便一搜就可以搜到的JSONP科普文,而重点要说的是jQuery下处理JSONP的一些坑!槽不多吐,直接去片。

首先我要搭建起一个服务器端的环境,才能继续进行下面的步骤。这个年头,不会点Nodejs都对不起前端开发这个Title,所以我选择了ExpressJS。在前端好基友Webstorm下搭建node服务器就是傻瓜式操作。

搞好服务器环境后,我们分别写两个“JSONP”的API。


在这里看到,两个function分别是jsonp和corejsonp。jsonp是我自己构造的一个方法,这是后面提到的内容重点所在。corejsonp则是Node ExpressJS框架封装好的返回jsonp的接口,用于和前者进行对比。这里我们可以看到第一个方法特别声明了respone的content-type为”text/plain”。下面开始体验:

这里你可能会说,有啥区别呢,两者都能正常工作啊,只是后者在控制台多了个warning的提醒:Resource interpreted as Script but transferred with MIME type text/plain 。这个提示是因为,向JSONP接口发起请求的时候,浏览器期望的响应格式为”text/javascript”或者”application/json”,而实际返回的格式却是”text/plain”,所以MIME type就不匹配了。下面对比感受一下:


可以看到,其实使用框架封装好的jsonp接口返回的是预期的”text/javascript”格式。这是第一种情况,就是服务器端会根据客户端发起的URI中的query而返回对应的callback名称,如下:

但我们日常工作中,经常会遇到的情况就是,服务器端返回的函数名称是固定的,而不是随着请求的URI而同步,这时候MIME Type就开始发挥他的作用了。这次我们将服务器端返回的函数名称固定为callme,再次上图感受一下。



好了,这时候我们看到了亮晶晶的报错了,callme is not defined。而且仔细的你还应该发现,我们在success回调函数里定义的console.info等操作也并没有执行。于是你就想,既然说callme没有定义,那我预先定义一个不也行么?于是就有了下面的一幕:

啊哈,函数再次被成功执行了。于是由于项目时间太赶啦,先上线了再说,剩下的你就没再去深究了。但作为一枚有志青年,岂能就此罢手。我们还是来研究一下为什么会这样子。其实我们看到,这里执行成功的只是预先定义好的callme函数,而不是jQuery里的success回调函数。也就是说,jQuery的这个get请求其实是理解成失败的。然后我们就跑去查一下jQuery的API,发现其中有个jsonpCallback,可以用于自定义回调函数名称,于是又赶紧尝试了一把:

然后发现,控制台有两次输出,第一次是callme函数的执行结果,第二次是success回调的执行结果。然后你又去把之前预先定义的callme删掉运行一次,于是意料之中的,控制台只有一次输出结果,那就是success回调的执行结果。你就想,其实决定jQuery的jsonp请求是否成功的真的是MIME Type么?为了解答你这个疑问,我又跑去把服务端的输出改为”text/javascript”:


咦~~,那个烦人的warning不见了,但一样是输出了两次结果。这时候有没有一种恍然大悟的感觉呢?其实决定jQuery的jsonp请求是否成功关键是服务器返回的函数名是否和jQuery发出去的的函数名是否一致。而服务器返回的响应,无论是什么格式只会影响浏览器的warning。稍等,真的是这样吗?不如我们再来改一改,这次服务器依然是返回json格式,但jsonpCallback和预定义的函数也改名了:

看完这个结果后,我们甚至可以看看返回的MIME Type是image时候的反应,注意这里预定义的函数名和jsonpCallback的名字:

说到这里,我的结论就是:MIME Type并非关键性因素,更重要的是服务器端返回的函数名

以上的测试是不是有种黑盒测试的感觉呢?于是我还尝试去阅读了一下jQuery最新版的关于ajax部分的源码,鉴于技术水平有限,对于代码的理解也不算透彻,只是大概看出个所以然,对于其中一些代码片段也加上了自己所理解的中文注释。有兴趣的小伙伴们可以研究一下,看不懂的也没关系,你要相信你以后再看会看懂的=。=

其实只要记住:JSONP的本质是执行服务器返回的script脚本。

所以下次负责jsonp相关的时候,记得提醒服务器端的小伙伴们返回javascript格式的,可以通过callback传参返回函数名的API哦。另外补充一点,MIME Type中text/html和text/plain的最大区别就是,前者是带格式的html文件,后者返回的只是纯粹的纯文本格式。最后还是那句:本文仅提供作者个人见解,难免错漏,如有问题,还望拍正!

jQuery处理JSONP的更多相关文章

  1. jQuery 调用jsonp实现与原理

    jQuery 调用jsonp实现与原理 您的评价:        收藏该经验     阅读目录 1.客户端代码 2.服务器端 通过jQuery实现JSONP 一般的ajax是不能跨域请求的,因此需要使 ...

  2. jQuery的jsonp跨域是这么回事.

    实现跨域请求的有iframe,img,script中的src属性.那么jquery是如何解决跨域请求的呢? 一:项目jsonp2中有个app.js文件,代码如下: function app(json) ...

  3. jquery ajax jsonp跨域调用实例代码

    今天研究了AJAX使用JSONP进行跨域调用的方法,发现使用GET方式和POST方式都可以进行跨域调用,这里简单分享下,方便需要的朋友 客户端代码 复制代码 代码如下: <%@ Page Lan ...

  4. 基于jQuery的Jsonp跨域[Get方式]

    由于目前的项目需要无刷新的跨域操作数据,整理了下自己使用的基于jQuery的Jsonp跨域[Get方式]. 代码如下: Javascript部分 $(function(){ $.ajax({ asyn ...

  5. jQuery中jsonp函数实现

    由于浏览器中的同源策略,不同的域名,不同的协议,甚至不同的端口都无法请求数据.因此出现了浏览器跨域请求数据问题. Jsonp是解决跨域问题的一个非常流行的方法. JSONP(JSON with Pad ...

  6. C# WebClient、jQuery ajax jsonp实现跨域

    WebClient 无传输数据获取 Uri uri = new Uri(allURL); WebClient wc = new WebClient(); wc.Encoding = System.Te ...

  7. 使用springMVC和Jquery实现JSONP

    JSONP这个东东是啥我就不写了,直接贴实现的代码 JAVA代码: /** * * 查询用户是否已经提交认证获取已经是认证会员 * * 使用spring mvc的直接返回string会遇到分号转义后字 ...

  8. 说说JSON和JSONP,也许你会豁然开朗,含jQuery使用jsonp用例

    [原创]说说JSON和JSONP,也许你会豁然开朗,含jQuery用例  前言: 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了 ...

  9. jQuery使用JSONP时的错误处理

    概述 什么是域,简单来说就是协议+域名或地址+端口,3者只要有任何一个不同就表示不在同一个域.跨域,就是在一个域中访问另一个域的数据. 如果只是加载另一个域的内容,而不需要访问其中的数据的话,跨域是很 ...

  10. JQuery Ajax jsonp

    JQuery ajax jsonp $.ajax({ method:"POST", url:"http://localhost:8081/ChenLei/PeopleSe ...

随机推荐

  1. Vue-cli 2.9 多页配置及多页面之间的跳转问题

    vue开发,现在大部分做的都是(SPA)应用,但是,由于,需求不同,我们针对的用户需求变更较为,频繁,如果每次都全量打包更新,给开发的自测,及测试妹子的任务就会多,每次都要重新验证一下才放心.所以,想 ...

  2. python 网络编程之socket开发和socketserver模块

    一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务端为你提供视频 ...

  3. (热死你)Resin https ssl Linux 配置,实战可用

    (热死你)Resin https ssl Linux 配置,实战可用 一.配置resin 1.在resin服务器中创建目录keys文件和openssl.conf,格式内容如下: #先复制以下的内容: ...

  4. (转)【干货】MySQL 5.7 多实例(多进程)配置教程

    原文:https://blog.csdn.net/zougen/article/details/79567744 https://klionsec.github.io/2017/09/20/mysql ...

  5. PSR2规范

    为了尽可能的提升阅读其他人代码时的效率,下面例举了一系列的通用规则,特别是有关于PHP代码风格的.各个成员项目间的共性组成了这组代码规范.当开发者们在多个项目中合作时,本指南将会成为所有这些项目中共用 ...

  6. linux MD5 SHA1 等 文件校验方法

    为解决官方发布的软件包被别人更改或者软件在传输过程中出现传输错误等问题,软件官方在提供软件包的同时,还提供一个保存MD5校验码的文件. Linux/unix中可以使用 md5sum 文件名 sha1s ...

  7. 《Algorithm算法》笔记:元素排序(2)——希尔排序

    <Algorithm算法>笔记:元素排序(2)——希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...

  8. HUE配置文件hue.ini 的impala模块详解(图文详解)(分HA集群)

    不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...

  9. CentOS和Ubuntu系统下安装 HttpFS (助推Hue部署搭建)

    不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...

  10. tomcat监控工具probe

    probe官网:http://www.lambdaprobe.org/ 但是已经链接至github了:https://github.com/psi-probe/psi-probe 下载psi-prob ...