问题:

页面中有一个按钮,点击之后会更新网页中的一个盒子的内容。

Ajax可以很容易的满足这种无须刷新整个页面就可以实现数据变换的需求。

但是,Ajax有一个缺点,就是他不允许跨域请求资源。

如果我的代码在codepen上,我不能将我的数据放到codepen网站上,那么我只能放到我自己的服务器中,这样的话,就无法通过Ajax访问到这个数据了。

解决:

想要实现这种跨域资源请求,有很多解决办法,列举出一部分:

  1. 让服务器来加载远程数据,然后在用户请求时提供给浏览器。
  2. 用<script>或是<iframe>标签加载外来文件。(因为他们的src属性允许获得任何地方的资源。)
  3. W3C制定的Cross-Origin Resource Sharing(CORS,跨域资源共享)。
  4. JSONP

JSONP的诞生及原理:

jsonp的原理其实和第二种解决方法一模一样,只不过他更加方便,然后这种跨域沟通的手段就被赋予了一个名字“JSONP”。

所以首先要弄懂第二种方式是怎么工作的:

原理:如果一个页面加载了一个外来的JS文件,浏览器就会自动执行这个文件中的代码。

所以假如localhost想要使用jsonhost上面的一个JSON数据,localhost就可以让jsonhost来帮他完成这件事情,jsonhost提供给他一个js文件,往要调用的函数中传入需要的数据,结果是和localhost自己调用函数的效果一模一样了。

jsonhost:

<script type="text/javascript">
   var json='["customername1","customername2"]';
   callbackFunction(json); 
</script>

localhost:

<script type="text/javascript">   var json='["customername1","customername2"]';   callbackFunction(json); </script><script type="text/javascript">function callbackFunction(result){var html = '<ul>';for(var i = 0; i < result.length; i++){html+= '<li>' + result[i] + '</li>';}html+= '</ul>';document.getElementById('divCustomers').innerHTML =html;}</script>

这样,localhost就已经可以使用jsonhost中的数据了。

然后localhost说,我希望可以在我的用户点击一次按扭时,就执行一遍callbackFunction(json),而不是页面加载后执行一次。

于是他就需要动态的创建<script>标签:

functioncallbackFunction(result)
{var html = '<ul>';for(var i = 0; i < result.length; i++){html+= '<li>' + result[i] + '</li>';}html+= '</ul>';document.getElementById('divCustomers').innerHTML =html;
}
$(".btn").click(function(){var script = document.createElement('script');script.setAttribute('src', "http://jsonhost/json.js");document.getElementsByTagName('header')[0].appendChild(script);
});

这样完成之后,效果就和用Ajax异步请求一样了。

到这里,故事仿佛就要这样结束了,但是突然有一天,另一个otherhost跑来和jsonhost说,他想要通过jsoncallbackFunction处理json,jsonhost就很为难,于是他们聚在一起,想要找到一个办法,可以不需要全部使用同一个函数名,也可以获取同一个数据。

最终他们想到了一个完美的办法——jsonhost用的函数名用一个变量代替,localhost和otherhost请求数据的时候,传入这个变量名,这样就可以各自决定各自使用的函数名了。

jsonhost:

<?phpheader('Content-type: application/json'); //告诉接收数据的对象此页面输出的是json数据$json = '["customername1","customername2"]';echo $_GET['callback'] . "(" .  $json . ")";?> 

localhost:

<script type="text/javascript">function getJson(url,funName){var script = document.createElement('script');script.setAttribute('src', url+funName);document.getElementsByTagName('head')[0].appendChild(script);}function callbackFunction(result){var html = '<ul>';for(var i = 0; i < result.length; i++){html+= '<li>' + result[i] + '</li>';}html+= '</ul>';document.getElementById('divCustomers').innerHTML =html;}$(".btn").click(function(){getJson("http://jsonhost/jsonp.php?jsoncallback=","callbackFunction");});</script>

otherhost:

<script type="text/javascript">functiongetJson(url,funName){var script = document.createElement('script');script.setAttribute('src', url+funName);document.getElementsByTagName('head')[0].appendChild(script);}function jsoncallbackFunction(result){console.log(result);}$(".btn").click(function(){getJson("http://jsonhost/jsonp.php?jsoncallback=","jsoncallbackFunction");});</script>

这样一来,使用什么函数名都是不同host自己的事情,他们互不干扰,jsonhost也不用操心这件事,专心提供数据就可以了。其他host也纷纷前来获取json。于是这种模式被广泛使用,然后这种通信方式就被命名为“JSONP”。

如果用jQuery的话,就不用自己命名函数并传递给参数了,因为这个函数名一点也不重要,他只是个代号而已,jQuery会帮我们自动生成一个函数名,然后将得到的数据传给这个函数。jQuery还会帮我们创建script标签, 我们只要关心如何处理这个数据就好了。

<script src="http://apps.bdimg.com/libs/jquery/1.8.3/jquery.js"></script>
<script>$.getJSON("http://jsonhost/jsonp.php?jsoncallback=?", function(data) {var html = '<ul>';for(var i = 0; i < data.length; i++){html+= '<li>' + data[i] + '</li>';}html+= '</ul>';$('#divCustomers').html(html);});</script>

jQuery把JSONP封装到Ajax里面,但本质上这两种技术是完全不同的。

JSONP的原理是,当前网页动态执行异域返回的js代码,这个代码是个执行请求数据的函数。浏览器执行这个函数,效果和当前域获得数据执行函数是一样的。

应用实例:

知道了原理之后,迫不及待的想要用一下JSONP来获取数据。这里用PHP来实现。

首先,需要有个服务器,如果没有服务器的话,可以使用wampserver软件模拟一个,这个软件还会建立一个集成环境,可以运行PHP文件。点击查看wampserver教程

有了自己的服务器和PHP运行环境之后,就可以开始了。想要在codepen上获取本地数据。

本机PHP:

<?php
header('Content-type: application/json'); //告诉接收数据的对象此页面输出的是json数据
$quotes= '[{"quote": "If you can\'t get rid of the skeleton in your closet, you\'d best teach it to dance.","author": "George Bernard Shaw"},{"quote": "We\'ll always have Paris.","author": "Casablanca"},{"quote": "A mathematician is a device for turning coffee into theorems.","author": "Paul Erdos"},{"quote": "Do, or do not. There is no \'try\'.","author": "Star Wars: Empire Strikes Back"},{"quote": "Some cause happiness wherever they go; others, whenever they go.","author": "Oscar Wilde"},{"quote": "Problems worthy of attack prove their worth by fighting back.","author": "Paul Erdos"},{"quote": "Maybe this world is another planet\'s Hell.","author": "Aldous Huxley"}]';echo $_GET['callback'] . "(" .  $quotes . ")";?> 

codepen上的js:

functionupdate(){var index=Math.floor(Math.random()*11);$.getJSON("http://localhost/quotes.php?callback=?",function(data){var num=Math.floor(Math.random()*6);$(".wrap").fadeOut(600,function(){$(".quo").html(data[num].quote);$(".auth").html(data[num].author);$("body, .quote-box button").css("background-color",colors[index]);$(".wrap").css("color",colors[index]);}).fadeIn(600);});
}$(document).ready(function(){update();$(".update").click(update);
});

点击查看在线demo,必须将本机模拟成服务器并建立PHP环境并添加了PHP文件才能运行。

而且要注意把codepen的https改成http。

成功之后可以看到,发送的请求中,传给callback的是一个jQuery自动生成的函数:

返回的也是这个函数调用数据:

如果不想自己配置的话,可以应用其他网站提供的API,实现原理是一样的。demo

参考:

  • JSONP 教程
  • 《jQuery基础教程》
  • 说说JSON和JSONP,也许你会豁然开朗,含jQuery用例

转载于:https://www.cnblogs.com/LiveWithIt/p/JSONP.html

JSONP的诞生、原理及应用实例相关推荐

  1. 强化学习(八) - 深度Q学习(Deep Q-learning, DQL,DQN)原理及相关实例

    深度Q学习原理及相关实例 8. 深度Q学习 8.1 经验回放 8.2 目标网络 8.3 相关算法 8.4 训练算法 8.5 深度Q学习实例 8.5.1 主程序 程序注释 8.5.2 DQN模型构建程序 ...

  2. Pacbio HiFi技术原理与应用软件实例

    Pacbio HiFi技术原理与应用软件实例 原创 生信技术 生信技术 2021-06-07 13:02 收录于话题 #基因组组装3个内容 #生物信息3个内容 #生信技术3个内容 点击上方蓝字关注我们 ...

  3. jsonp 跨域原理详解

    转载至:http://zha-zi.iteye.com/blog/1975116 JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制 ...

  4. jsonp跨域原理_【网站技术解读①】Javascript实现跨域请求

    推荐一个读者做的不错的编程学习网站: 网站:潜安 域名:http://www.qianani.com 另外将会不定期推送近期网站用到的一些技术,讲一些核心原理,今天为第一篇 问题由来: 最近一直在优化 ...

  5. Adaboost算法原理分析和实例+代码(简明易懂)

    Adaboost算法原理分析和实例+代码(简明易懂) [尊重原创,转载请注明出处] http://blog.csdn.net/guyuealian/article/details/70995333   ...

  6. python实现dos攻击_dos攻击原理及攻击实例

    DoS是Denial of Service的简称,即拒绝服务,造成DoS的攻击行为被称为DoS攻击,其目的是使计算机或网络无法提供正常的服务.最常见的DoS攻击有计算机网络带宽攻击和连通性攻击. Do ...

  7. PHP中对数组进行分页处理的原理及分页实例

    PHP中对数组进行分页处理的原理及分页实例 最近用到了用数组数据分页,所以就整理了一下,希望能对大家有用! <?php class PaginationArray{    public $pag ...

  8. 断点续传的原理剖析与实例讲解

    断点续传的原理剖析与实例讲解 本文所要讲的是Android断点续传的内容,以实例的形式进行了详细介绍. 一.断点续传的原理 其实断点续传的原理很简单,就是在http的请求上和一般的下载有所不同而已. ...

  9. 9.jsonp的实现原理

    1. 由于浏览器的安全性限制,不允许AJAX访问 协议不同.域名不同.端口号不同的数据接口,浏览器认为这种访问不安全: 2. 以通过动态创建script标签的形式,把script标签的src属性,指向 ...

最新文章

  1. Azure AI的又一里程碑,Neural TTS新模型呈现真人般情感饱满的AI语音
  2. FC3服务器配置一条龙
  3. faster rcnn流程
  4. java dubbo 方案,Missing artifact com.alibaba:dubbo:jar:2.8.4 dubbo解决方案
  5. 计算机院校考研非歧视,2021考研昌吉学院学科教学(语文)045103调剂信息
  6. html标签元素分类
  7. VS使用SDL2时LNK2019无法解析的外部符号_main
  8. 软件评测师考试需要知道什么?
  9. 知行EDI系统Excel方案对比集成业务系统方案
  10. 自己读Go程序设计语言的一些总结(更新ing...)
  11. 《运筹学》CSU作业答案
  12. 【2022省选模拟】叮叮车——卡特兰数、数位DP
  13. CSS:不可思议的border属性
  14. 【Python 】turtle库之 玫瑰曲线
  15. 互联网应届生四项职场生存技能
  16. OPENCV的下载和安装
  17. 2018年6月东莞车牌迁入广州操作流程讲解 白云区车管所
  18. 商城 mysql语句_简单商城的数据库建表sql
  19. Linux 单用户修改root密码
  20. 用正则表达式爬取糗图的图片和一些励志语句

热门文章

  1. Binder实用指南(二) - 实战篇
  2. Apk去签名校验详解
  3. 工人物语5战役攻略_《工人物语7》入门详细图文攻略
  4. python运算符讲解_3.Python运算符详解
  5. JZOJ 5404. 【NOIP2017提高A组模拟10.10】Graph
  6. 给计算机系统的资产分配的记号被称为什么,哈工大2015计算机复试试题(25页)-原创力文档...
  7. html表单页脚,HTML 表格
  8. word编辑论文技巧
  9. 元胞自动机(Cellular Automata)
  10. [总结] 平衡树总结