跨域知识——JSONP

Posted baoyadong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨域知识——JSONP相关的知识,希望对你有一定的参考价值。

JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。

它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了

如果对于callback参数如何使用还有些模糊的话,我们后面会有具体的实例来讲解。

首先,网页动态插入<script>元素,由它向跨源网址发出请求。

 1 <h1>绕过浏览器禁止跨域请求的方案之八——JSONP</h1>
 2   <button id="bt1">请求数据</button>
 3   <script src="jquery-1.11.3.js"></script>
 4   <script>
 5     //声明静态函数 —— 客户端不直接调用
 6     function doRes(data){
 7       console.log(\'开始处理服务器端返回的数据\')
 8       console.log(data);
 9     }
10 
11 
12     $(\'#bt1\').click(function(){
13       //动态创建一个SCRIPT标签,添加到DOM
14       var s = document.createElement(\'script\');
15       s.setAttribute(\'async\', \'true\'); //脚本异步执行
16       s.src = \'http://localhost/crossdomain/4.php?callback=doRes\';
17       document.body.appendChild(s);
18       //OM树上追加了新的SCRIPT,浏览器就
19       //会立即请求该资源并执行服务器返回的JS
20      
21     })

上面代码通过动态添加<script>元素,向服务器http://localhost/crossdomain/4.php发出请求。

注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。

 

2.基于jquery的跨域

jquery发起跨域请求,有两种方法:

 (1)$.getJSON()

XHR非跨域请求:

                      $.getJSON(\'x.php\', function(){})

SCRIPT实现JSONP请求

                     $.getJSON(\'跨域地址/x.php?callback=?\', function(){})

  (2)$.ajax()

       XHR非跨域请求:

              $.ajax({....})

      SCRIPT实现JSONP请求:

              $.ajax({

               url: \'跨域地址/x.php\',

              dataType:\'jsonp\',

              success: function(){ ... }

                                                       })

demo1如下:

 1 <h1>jQuery.getJSON与跨域请求</h1>
 2   <button id="bt1">请求数据(非跨域)</button>
 3   <button id="bt2">请求数据(跨域)</button>
 4   <script src="jquery-1.11.3.js"></script>
 5   <script>
 6     $(\'#bt1\').click(function(){
 7       //XHR非跨域
 8       $.getJSON(\'5-1.php\', function(data){
 9         console.log(\'1 处理服务器返回的数据\')
10         console.log(data);
11       })
12     });
13 
14     $(\'#bt2\').click(function(){
15       //XHR跨域 —— 浏览器禁止
16       // $.getJSON(\'http://localhost/crossdomain/5-1.php?\', function(data){
17       //   console.log(\'2 处理服务器返回的数据\')
18       //   console.log(data);
19       // })
20 
21       $.getJSON(\'http://localhost/crossdomain/5-2.php?callback=?\',function(data){
22         console.log(\'3 处理服务器返回的数据\')
23         console.log(data);
24       })
25     });

jquery在处理jsonp类型的ajax时(还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮

你生成回调函数并把数据取出来供success属性方法来调用。

在服务器端,代码如下:

 1 <?php
 2 //header(\'Content-Type: application/json\');
 3 header(\'Content-Type: application/javascript\');
 4 sleep(10);  //让当前解释器暂停执行10s
 5 $cb = $_REQUEST[\'callback\'];
 6 $data = [
 7   \'ename\'=>\'Tom\',
 8   \'age\'=>20
 9 ];
10 echo  $cb. \'(\' .json_encode($data) . \')\';

demo2如下:

<h1>jQuery.ajax与跨域请求</h1>
  <button id="bt1">请求数据(非跨域)</button>
  <button id="bt2">请求数据(跨域)</button>
  <script src="jquery-1.11.3.js"></script>
  <script>
    $(\'#bt1\').click(function(){
      //XHR非跨域
      $.ajax({
        url: \'6-1.php\',
        success: function(){}
      })
    });

    $(\'#bt2\').click(function(){
      $.ajax({
        url: \'http://localhost/crossdomain/6-2.php\',
        dataType: \'jsonp\',  //指定响应消息的数据类型
        success: function(data){
          console.log(\'4 开始处理响应数据\')
          console.log(data);

        }
      });
    });

  

 

 

 

 

 

以上是关于跨域知识——JSONP的主要内容,如果未能解决你的问题,请参考以下文章

跨域知识——JSONP

跨域问题相关知识详解(原生js和jquery两种方法实现jsonp跨域)

跨域解决方案 - JSONP

ajax跨域之jsonp

jsonp 方式处理跨域前后端代码如何配合?

前端 - jsonp 跨域ajax