跨域知识(二)——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);

        }
      });
    });

  

 

 

原文地址:https://www.cnblogs.com/xuzhudong/p/7045872.html