关于JSONP

1.什么是JSONP

Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。JSONP并不是一种正式传输协议,允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

2.JSONP和AJAX

ajax和jsonp这两种技术在调用方式上”看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装。

但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加。

3.为什么Ajax不能跨域请求?

浏览器的同源策略,使得AJAX请求只能发给同源的网址,否则就报错。试想如果Ajax可以偷偷摸摸发请求,而不需要用户操作,用户不知情,那么问题就大了,如果你上了一个不安全的网站,这个网站Ajax偷偷发一个请求到你的网银网站(这里跨域了)拿到你的Cookie,把Cookie传到这个不安全的网站自己的服务器,那么你的网银就会被盗。所以浏览器不允许Ajax跨域。

AJAX请求:

<!DOCTYPE html>  
<html>  
<head>  
<meta charset=" utf-8">  
<meta name="author" content="http://www.softwhy.com/" />  
<title>蚂蚁部落</title>  
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script>
$.ajax({
  type:'get',
  url:'http://www.softwhy.com/demo/JSON/php/antzone.php'
});
</script>
</head> 
<body> 
<div id="thediv"></div>
</body> 
</html>

将这段代码复制之后在浏览器运行,会出现跨域问题,截图如下:

在这里插入图片描述

4.JSONP的实现

Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<\script>、<\img>、<\iframe>)

我们希望获取跨域服务器上获取xml文件上的如下数据,并且显示在指定的div中,xml文件内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<bookstore>
  <book>
    <range>前端专区</range>
    <author>蚂蚁部落</author>
    <target>css教程</target>
  </book>
  <book>
    <range>前端专区</range>
    <author>蚂蚁部落</author>
    <target>div教程</target>
  </book>
  <book>
    <range>资源专区</range>
    <author>softwhy.com</author>
    <target>特效下载</target>
  </book>
  <book>
    <range>前端专区</range>
    <author>softwhy.com</author>
    <target>教程下载</target>
  </book>
</bookstore>

很明显不能使用ajax跨域请求此xml文件,然后进行处理。

那么JSONP就要出场了,首先通过后台语言将上面的XML文件内容转换为JSON格式,看如下代码:

<?php
  $path=$_SERVER["DOCUMENT_ROOT"].'/demo/JSON/XML/XML.xml';
  $json=json_encode(simplexml_load_file($path));
?>

转换结果如下:在这里插入图片描述

上面的unicode字符是将中文进行了转码,可以防止出现乱码的情况。

然后在客户端我们需要动态的创建一个<script>标签,然后再进行请求以便实现跨域效果:

function getBooks(){
  var script=document.createElement('script');
  script.setAttribute('type','text/javascript');
  script.setAttribute('src','http://www.softwhy.com/demo/JSON/PHP/antzone.php?callback=Books');
  document.body.appendChild(script);
}

上面的代码动态创建了一个script标签,然后设置标签的src属性值,这个属性值最关键的地方是传送一个函数的名称,这个名称会在php后台经过处理包装后,作为一个函数调用的形式返回,函数的参数就是转换后的json格式数据,后台转换代码:

<?php
  $path=$_SERVER["DOCUMENT_ROOT"].'/demo/JSON/XML/XML.xml';
  $json=json_encode(simplexml_load_file($path));
  $callbackFn=$_GET['callback'];
  echo "$callbackFn($json);";
?>

完整前台代码实例:

<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>蚂蚁部落</title>
<script>
function books(books){
  var books=books.book;
  var booksContainer=document.getElementById('books');
  var str="";
  for(var index=0;index<books.length;index++){
    str=str+"<div>"+
      books[index]["range"]+","+
      books[index]["author"]+","+
       books[index]["target"]+
     "</div>";
  }
  booksContainer.innerHTML=str
}
function getBooks(){
  var script=document.createElement('script');
  script.setAttribute('type','text/javascript');
  script.setAttribute('src','http://www.softwhy.com/demo/JSON/php/antzone.php?callback=books');
  document.body.appendChild(script);
}
window.onload=function(){
  getBooks();
}
</script>
</head>
<body>
<div id="books"></div>
</body>
</html>
4.JSONP的封装

代码封装一下,以便于与用户界面交互,从而实现多次和重复调用,这里使用jQuery实现jsonp调用

jquery在处理jsonp类型的ajax时,自动帮你生成回调函数并把数据取出来供success属性方法来调用

$.ajax的参数:
  • type:请求方式 GET/POST
  • url:请求地址
  • async:布尔类型,默认为true 表示请求是否为异步,如果为false表示为同步。
  • dataType:返回的数据类型
  • jsonp:传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
  • jsonpCallback:自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
  • success:调用成功执行的函数
  • error:异常处理函数
<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>蚂蚁部落</title>
<script type="text/javascript">
    jQuery(document).ready(function () {
        function books(books) {
        var books = books.book;
        var booksContainer = document.getElementById('books');
        var str = "";
        for (var index = 0; index < books.length; index++) {
            str = str + "<div>" +
                books[index]["range"] + "," +
                books[index]["author"] + "," +
                books[index]["target"] +
                "</div>";
        }
        booksContainer.innerHTML = str
    }
        $.ajax({
            type: "get",
            async: false,
            url: "http://www.softwhy.com/demo/JSON/php/antzone.php?callback=books",
            dataType: "jsonp",
            jsonp: "callback", //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
            jsonpCallback: "books", //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
            success: function (json) {
                books(json)
            },
            error: function () {
                console.log('fail');
            }
        });
    });
</script>
</head>
<body>
   <div id="books"></div>
</body>
</html>
5.总结

(1)JSONP并不是一个官方的标准协议,而是程序员自己达成的一种约定俗成。

(2)实现跨域就是利用<script>标签自带的跨域能力。

(3)在请求页面创建一个用来处理数据的函数。

(4)处理数据的函数名称会被发送到服务器,经过包装以后,要被处理的数据被当作函数的参数返回。

(5)后台包装返回的字符串通过src加入scrpt标签后就是一个js函数调用代码,于是跨域请求成功。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值