问题:
页面中有一个按钮,点击之后会更新网页中的一个盒子的内容。
Ajax可以很容易的满足这种无须刷新整个页面就可以实现数据变换的需求。
但是,Ajax有一个缺点,就是他不允许跨域请求资源。
如果我的代码在codepen上,我不能将我的数据放到codepen网站上,那么我只能放到我自己的服务器中,这样的话,就无法通过Ajax访问到这个数据了。
解决:
想要实现这种跨域资源请求,有很多解决办法,列举出一部分:
- 让服务器来加载远程数据,然后在用户请求时提供给浏览器。
- 用<script>或是<iframe>标签加载外来文件。(因为他们的src属性允许获得任何地方的资源。)
- W3C制定的Cross-Origin Resource Sharing(CORS,跨域资源共享)。
- 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>标签:
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(){
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:
<?php
header('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"> function getJson(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:
function update(){
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用例
JSONP的诞生、原理及应用实例的更多相关文章
-
VUE -- JSONP的诞生、原理及应用实例
问题: 页面中有一个按钮,点击之后会更新网页中的一个盒子的内容. Ajax可以很容易的满足这种无须刷新整个页面就可以实现数据变换的需求. 但是,Ajax有一个缺点,就是他不允许跨域请求资源. 如果我的 ...
-
jQuery 调用jsonp实现与原理
jQuery 调用jsonp实现与原理 您的评价: 收藏该经验 阅读目录 1.客户端代码 2.服务器端 通过jQuery实现JSONP 一般的ajax是不能跨域请求的,因此需要使 ...
-
jsonp跨域原理
Jsonp原理: 首先在客户端注册一个callback (如:'jsoncallback'), 然后把callback的名字(如:jsonp1236827957501)传给服务器.注意:服务端得到ca ...
-
jsonp 跨域原理详解
JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略).这一策略对于Java ...
-
jsonp的工作原理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
-
Win Socket编程原理及简单实例
[转]http://www.cnblogs.com/tornadomeet/archive/2012/04/11/2442140.html 使用Linux Socket做了小型的分布式,如Linux ...
-
9.jsonp的实现原理
1. 由于浏览器的安全性限制,不允许AJAX访问 协议不同.域名不同.端口号不同的数据接口,浏览器认为这种访问不安全:2. 以通过动态创建script标签的形式,把script标签的src属性,指向数 ...
-
Python实现的选择排序算法原理与用法实例分析
Python实现的选择排序算法原理与用法实例分析 这篇文章主要介绍了Python实现的选择排序算法,简单描述了选择排序的原理,并结合实例形式分析了Python实现与应用选择排序的具体操作技巧,需要的朋 ...
-
jsonp的实现原理
jsonp的实现原理 由于浏览器的安全性(同源策略)限制,不允许AJAX访问协议不同或域名不同或端口号不同的数据接口: 可以通过动态创建script标签的方式,把script标签的src属性指向数据接 ...
随机推荐
-
【先定一个小目标】Redis 安装成windows服务-开机自启
1.第一步安装成windows服务的,开机自启动 redis-server --service-install redis.windows.conf 2.启动\关闭 redis-server --se ...
-
JS对象的几个方法介绍
1.hasOwnProperty 判断是不是对象自身的属性,如果是继承的返回false否则true function Fn(){ } Fn.prototype.num = 10; var obj = ...
-
30天,APP创业从0到1【7.25上海站】
活动概况 时间:2015年7月25日13:30-16:30 地点:太库•上海孵化器(张江金科路2889号长泰广场c座12楼) 主办:APICloud.诸葛.圣诺资讯 联合主办:微链.太库•上海孵化器 ...
-
jnlp jws
http://www.mkyong.com/java/java-web-start-jnlp-tutorial-unofficial-guide/
-
xx
[git]merge和rebase的区别 - 削微寒 - 博客园 http://www.cnblogs.com/vamei/p/3480994.html 协议森林16 小美的桌号(DHCP协议) - ...
-
PHP发送微信模版消息
public function payResult($params) { global $_GPC, $_W; $weid = $this->_weid; $order = pdo_fetch( ...
-
PHP学习笔记1.2——预定义变量参考
预定义变量和用户自定义变量在使用上没有区别,大多数预定义变量的执行结果都是服务器的相关信息(如:版本号.路径.错误参数等),所以我们很少将其用于网站前台开发,如果被别有用心得人知道了后,会严重威胁服务 ...
-
Git教程--Git分支管理
分支管理--原理分析 在前面讲到的版本回退里,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.只有一条时间线的这条分支称为master,HEAD严格来说不是指向提交,而是指向maste ...
-
mysql的分表与分区的区别
http://www.2cto.com/database/201503/380348.html
-
Python 入门基础12 --函数基础5 匿名函数、内置函数
今日内容: 1.三元表达式 2.列表.元组生成式 | 字典生成式 3.递归 4.匿名函数 5.内置函数 一.三元表达式 三元运算符:就是 if...else... 语法糖 前提:if 和 else # ...