首页 web前端 js教程 Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别_javascript技巧

Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别_javascript技巧

May 16, 2016 pm 03:22 PM

前言

  第一次听说jsonp,其实早在2年之前。当时在做一个活动页面的抽奖模块,要从服务端get一个概率,当时什么都不懂,同事说用ajax,我就用ajax,同事说dataType改成jsonp,我就改成jsonp。于是乎活动页面做完了,以后也没有碰到过jsonp,在这期间我一直以为jsonp跟ajax息息相关,是xhr的一种特殊的跨域形式...直到一个月前的一次面试,问到jsonp我被虐成狗,才决定看下jsonp,好吧,原来jsonp也不是很难。

为什么要用jsonp?

  相信大家对跨域一定不陌生,对同源策略也同样熟悉。什么,你没听过?没关系,既然是深入浅出,那就从头说起。

  假如我写了个index页面,页面里有个请求,请求的是一个json数据(不知道json数据的猛戳JSON简介以及用法汇总),简单思考写下如下代码:

<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost/a.json',
 dataType: "json",
 success: function (data) {
  console.log(data);
 }
 })
</script> 
{
 "name": "hanzichi",
 "age": 10
} 
登录后复制

  楼主把两个文件都放在wamp下的www文件夹下,ajax请求没有跨域,完美得到结果:

  但是如果我的json文件和index文件不在一个域下,即跨域(不懂跨域的可参考JavaScript 的同源策略)了呢?

  试着在wamp下新开个apache端口(不知道怎么开的可参考WampServer下使用多端口访问),将json文件放到该服务端口的文件夹下(楼主设置的端口号为8080,默认的是80端口),试着发送请求:

<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost:8080/a.json',
 dataType: "json",
 success: function (data) {
  console.log(data);
 }
 })
</script> 
登录后复制

  很显然,提示跨域了!怎么搞?这时jsonp就要出马了!

神奇的script标签

  与jsonp息息相关的是script标签,而xhr或者说传统意义上的ajax与之没有半毛钱关系!

  接着看上面的index.html代码,我们看到页面引用了百度cdn的jquery路径,对于这样的方式我们似乎已经习以为常,但是仔细一想,script标签可是完完全全的跨域的啊...没错,jsonp的实现核心就是利用script标签的跨域能力!于是我们灵机一动,似乎可以这么搞,动态生成一个script标签,把json的url赋值给script的src属性,然后再把这个script标签插入dom里...

<body>
 <script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
 <script type="text/javascript">
 var s = document.createElement('script');
 s.src = 'http://localhost:8080/a.json';
 document.body.appendChild(s);
 </script>
</body> 
登录后复制

  我们创建了一个script标签,而标签内包裹的内容正是需要的json数据,但是报错如下:

  原因是因为json数据并不是合法的js语句,把上面的json数据放在一个回调函数中是最简单的方法:

<body>
 <script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
 <script type="text/javascript">
 function jsonpcallback(json) {
  console.log(json);
 }
 var s = document.createElement('script');
 s.src = 'http://localhost:8080/a.json';
 document.body.appendChild(s);
 </script>
</body> 
jsonpcallback({
 "name": "hanzichi",
 "age": 10
}); 
登录后复制

  当然,这时的a.json文件并不一定要这样命名,改成a.js也不会有一点问题。

  而如果是与服务端交互也是一样的道理,比如和php:

<body>
 <script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
 <script type="text/javascript">
 function jsonpcallback(json) {
  console.log(json);
 }
 var s = document.createElement('script');
 s.src="http://localhost:8080/test.php&#63;callback=jsonpcallback";
 document.body.appendChild(s);
 </script>
</body> 
<&#63;php
 $jsondata = '{
 "name": "hanzichi",
 "age": 10
 }';
 echo $_GET['callback'].'('.$jsondata.')';
&#63;> 
登录后复制

  需要注意的是,jsonp提供的url(即动态生成的script标签的src),无论看上去是什么形式,最终生成返回的都是一段js代码。

JQuery对jsonp的封装

  为了便于开发,jq对jsonp也进行了封装,封装在了ajax方法中。

<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost:8080/a.json',
 dataType: 'jsonp',
 jsonpCallback: 'CallBack',
 success: function (data) {
  console.log(data);
 }
 });
</script> 
CallBack({
 "name": "hanzichi",
 "age": 10
}); 
登录后复制

  以上代码是针对请求文件中写死了callback函数名的情况。因为请求的是json文件,json不是服务器端的动态语言不能进行解析,如果是php或者其他的服务器端语言,则不用写死函数名,比如下面这样:

<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost:8080/test.php',
 dataType: 'jsonp',
 success: function (data) {
  console.log(data);
 }
 });
</script> 
<&#63;php
 $jsondata = '{
 "name": "hanzichi",
 "age": 10
 }';
 echo $_GET['callback'].'('.$jsondata.')';
&#63;> 
登录后复制

当然类似的封装好的方法还有几种:

// 1
$.getJSON("http://localhost:8080/test.php&#63;callback=&#63;", function(data) { 
 console.log(data);
});
// 2
$.get('http://localhost:8080/test.php', function(data) { 
 console.log(data);
}, 'jsonp'); 
登录后复制

  需要注意的是getJSON方法的请求地址url需要带上callback=?,因为jq对该方法进行封装的时候并没有默认回调函数变量名为callback,于是php中$_GET['callback']就找不到变量值了。

  而一般的jq方法url 中不用指定 callback 参数。对于 jQuery 中的 jsonp 来说,callback 参数是自动添加的。默认情况下,jQuery 生成的 jsonp 请求中 callback 参数是形如 callback=jQuery200023559735575690866_1434954892929 这种根据看似随机的名字,对应的就是 success 那个处理函数,所以一般不用特意处理。二如果要写死callback名的话,可以参照上文。

 

总结

  由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求,这就是jsonp的核心。

  jsonp原理:

 1.首先在客户端注册一个callback, 然后把callback的名字传给服务器。
 2.服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
 3.客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

 json和jsonp的区别,ajax和jsonp的区别

 json和jsonp虽然只有一个字母的区别,但是它们之间扯不上关系。

json是一种轻量级的数据交换格式。

jsonp是一种跨域数据交互协议。

json的优点:(1)基于纯文本传递极其简单,(2)轻量级数据格式适合互联网传递,(3)容易编写和解析。

ajax和jsonp的区别:

相同点:都是请求一个url

不同点:ajax的核心是通过xmlHttpRequest获取内容

    jsonp的核心则是动态添加<script>标签来调用服务器 提供的js脚本。</script>

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

前端热敏纸小票打印遇到乱码问题怎么办? 前端热敏纸小票打印遇到乱码问题怎么办? Apr 04, 2025 pm 02:42 PM

前端热敏纸小票打印的常见问题与解决方案在前端开发中,小票打印是一个常见的需求。然而,很多开发者在实...

谁得到更多的Python或JavaScript? 谁得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript开发者的薪资没有绝对的高低,具体取决于技能和行业需求。1.Python在数据科学和机器学习领域可能薪资更高。2.JavaScript在前端和全栈开发中需求大,薪资也可观。3.影响因素包括经验、地理位置、公司规模和特定技能。

神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? 如何使用JavaScript将具有相同ID的数组元素合并到一个对象中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中将具有相同ID的数组元素合并到一个对象中?在处理数据时,我们常常会遇到需要将具有相同ID�...

如何实现视差滚动和元素动画效果,像资生堂官网那样?
或者:
怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? 如何实现视差滚动和元素动画效果,像资生堂官网那样? 或者: 怎样才能像资生堂官网一样,实现页面滚动伴随的动画效果? Apr 04, 2025 pm 05:36 PM

实现视差滚动和元素动画效果的探讨本文将探讨如何实现类似资生堂官网(https://www.shiseido.co.jp/sb/wonderland/)中�...

console.log输出结果差异:两次调用为何不同? console.log输出结果差异:两次调用为何不同? Apr 04, 2025 pm 05:12 PM

深入探讨console.log输出差异的根源本文将分析一段代码中console.log函数输出结果的差异,并解释其背后的原因。�...

JavaScript难以学习吗? JavaScript难以学习吗? Apr 03, 2025 am 12:20 AM

学习JavaScript不难,但有挑战。1)理解基础概念如变量、数据类型、函数等。2)掌握异步编程,通过事件循环实现。3)使用DOM操作和Promise处理异步请求。4)避免常见错误,使用调试技巧。5)优化性能,遵循最佳实践。

PowerPoint可以运行JavaScript吗? PowerPoint可以运行JavaScript吗? Apr 01, 2025 pm 05:17 PM

在PowerPoint中可以运行JavaScript,通过VBA调用外部JavaScript文件或嵌入HTML文件来实现。1.使用VBA调用JavaScript文件,需启用宏并具备VBA编程知识。2.嵌入包含JavaScript的HTML文件,简单易行但受安全限制。优点包括扩展功能和灵活性,劣势涉及安全性、兼容性和复杂性,实际应用需注意安全性、兼容性、性能和用户体验。

See all articles