AngularJs中的JSONP跨域访问数据传输问题

json 、jsonp

一个是JavaScript Object Notation,一个是JSON with Padding ,二个很像,但是其实不是一回事。JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明创建出来的非官方数据交互协议。JSON是描述信息的格式,JSONP是信息传递双方约定的方法。

注意:现在浏览器是存在同源策略这个机制的,在全局层面禁止了页面加载或执行与自身来源不同的域的任何脚本。而jsonp是一种跨域绕过浏览器的安全限制,从不同的域请求数据的方法。

jsonp其实是模拟web页面上script调用js文件来实现跨域调用数据的。(不仅如此,我们还发现方式拥有“src”“href”这些属性的标签都似乎有跨域的能力,比如script、img、iframe;

如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;JSON的纯字符数据格式可以简洁的描述复杂数据,被js原生支持,所以在web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。

JSONP的原理是通过script标签发起一个GET请求来取代XHR请求。JSONP生成一个script标签并插到DOM中,然后浏览器会接管并向src属性所指向的地址发送请求。

当服务器返回请求时,响应结果会被包装成一个JavaScript函数,并由该请求所对应的回调函数调用。

AngularJS在 httpJSONP http服务的jsonp方法可以发送请求,如下所示:

     $http .jsonp("https://api.github.com?callback=JSON_CALLBACK") .success(function(data) { 

  // 数据
});

当请求被发送时,AngularJS会在DOM中生成一个如下所示< script>
标签:

  <script src="https://api.github.com?callback=angular.callbacks._0" type="text/javascript"></script> 

注意,JSON_CALLBACK被替换成了一个特地为此请求生成的自定义函数。当支持JSOPN的服务器返回数据时,数据会被包装在由AngularJS生成的具名函数angular.callbacks._0中在这个例子中,GitHub服务器会返回包含在回调函数中的JSON数据,响应看起来如下所示: 

 // 简写  

  angular.callbacks._0({

    ‘meta‘: {
      ‘X-RateLimit-Limit‘: ‘60‘,
      ‘status‘: 200
    },
    ‘data‘: {
      ‘current_user_url‘: ‘https://api.github.com/user
    }
  })
当AngularJS调用指定的回调函数时会对$http的promise对象进行resolve。当我们自己开发支持JSONP的后端服务时,要确保响应的数据被包含在请求所指定的回调函数中。使用JSONP需要意识到潜在的安全风险。首先,服务器会完全开放,允许后端服务调用应用中的任何JavaScript。不受我们控制的外部站点(或者蓄意攻击者)可以随时更改脚本,使我们的整个站点变得脆弱。服务器或中间人有可能会将额外的JavaScript逻辑返回给页面,从而将用户的隐私数据暴露出来。由于请求是由script标签发送的,所以只能通过JSONP发送GET请求。并且脚本的异常也很难处理。使用JSONP一定要谨慎,同时只跟信任并可以控制的服务器进行通信。

一句话就是利用script标签绕过同源策略,获得一个类似这样的数据,jsonpcallback是页面存在的回调方法,参数就是想得到的json。

看下面案列
Jquery中jsonp的使用

myUrl = 'http://localhost:8090/api/test';

$.ajax({
    type:'GET',
    url:myUrl,
    dataType:'jsonp',
    jsonp:'callback',
    jsonpCallback:'jsonpCallback',
    success:function(data){
        alert(data.msg);
    }
});

function jsonpCallback(data){
    alert(data);
    }

1.jsonp只能使用get请求,解决同源问题,返回javascript代码,因为请求javascript文件是没有同源问题的。
2.当请求数据类型为jsonp时,会将callback=jsonpCallback加在url上,http://localhost:8090/api/testcallback=jsonpCallback
3.前台javascript中定义jsonpCallback函数,此函数必须定义在window下,也就是全局的函数,否则找不到。
4.后台获取请求的callback参数值jsonpCallback,返回字符串”jsonpCallback(result)”,result为返回结果。
5.请求返回的是script tag,首先会调用jsonpCallback函数,不管是否找到该函数,都会调用success函数。
6.如果没有定义jsonp和jsonpCallback,jsonp默认为”callback”,jsonpCallback会是Jquery自动生成的函数名。

angularJS中的jsonp的使用

myUrl = "http://localhost:8090/api/testcallback=JSON_CALLBACK";

$http.jsonp(myUrl).success(
  function(data){
    alert(data);
  }
);
或
$http.jsonp(myUrl,{
    params:{
        abc:?,
        callback:'JSON_CALLBACK'
    }
}).success(
  function(data){
    alert(data);
  }
);

1.angularJS中使用$http.jsonp函数
2.指定callback和回调函数名,函数名为JSON_CALLBACK时,会调用success回调函数,JSON_CALLBACK必须全为大写。
3.也可以指定其它回调函数,但必须是定义在window下的全局函数。
4.url中必须加上callback
5.当callback为JSON_CALLBACK时,只会调用success,即使window中有JSON_CALLBACK函数,也不会调用该函数。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值