AngularJS实现的JSONP跨域访问数据传输功能详解


Posted in Javascript onJuly 20, 2017

本文实例讲述了AngularJS实现的JSONP跨域访问数据传输功能。分享给大家供大家参考,具体如下:

大家会自然想到只有一个字母之差的JSON吧~

JSON(JavaScript Object Notation)JSONP(JSON with Padding)虽然只有一个字母的差别,但其实他们根本不是一回事儿

JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。我们拿最近比较火的谍战片来打个比方,JSON是地下党们用来书写和交换情报的“暗号”,而JSONP则是把用暗号书写的情报传递给自己同志时使用的接头方式。看到没?一个是描述信息的格式,一个是信息传递双方约定的方法。

浏览器是存在同源策略这个机制的,在全局层面禁止了页面加载或执行与自身来源不同的域的任何脚本。

JSONP是一种可以绕过浏览器的安全限制,从不同的域请求数据的方法。

Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<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在http服务中提供了一个JSONP辅助函数。通过http服务中提供了一个JSONP辅助函数。通过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/test?callback=JSON_CALLBACK";
$http.jsonp(myUrl).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函数,也不会调用该函数。

希望本文所述对大家AngularJS程序设计有所帮助。

Javascript 相关文章推荐
javascript中的继承实例代码
Apr 27 Javascript
使用apply方法处理数组的三个技巧[译]
Sep 20 Javascript
调用innerHTML之后onclick失效问题的解决方法
Jan 28 Javascript
jQuery中的编程范式详解
Dec 15 Javascript
JavaScript各类型的关系图解
Oct 16 Javascript
jQuery实现带有动画效果的回到顶部和底部代码
Nov 04 Javascript
全面了解JavaScript的数据类型转换
Jul 01 Javascript
深入解析Javascript闭包的功能及实现方法
Jul 10 Javascript
Ajax分页插件Pagination从前台jQuery到后端java总结
Jul 22 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
Jun 30 Javascript
JS通用方法触发点击事件代码实例
Feb 17 Javascript
微信小程序点击item使之滚动到屏幕中间位置
Mar 25 Javascript
深入探究node之Transform
Jul 20 #Javascript
微信小程序“摇一摇”的实例代码
Jul 20 #Javascript
基于JavaScript实现微信抢红包功能
Jul 20 #Javascript
ReactNative短信验证码倒计时控件的实现代码
Jul 20 #Javascript
基于jQuery实现手风琴菜单、层级菜单、置顶菜单、无缝滚动效果
Jul 20 #jQuery
详解Angular CLI + Electron 开发环境搭建
Jul 20 #Javascript
JavaScript 基础表单验证示例(纯Js实现)
Jul 20 #Javascript
You might like
PHP HTML JavaScript MySQL代码如何互相传值的方法分享
2012/09/30 PHP
微信公众号开发之语音消息识别php代码
2016/08/08 PHP
[原创]PHPCMS遭遇会员投稿审核无效的解决方法
2017/01/11 PHP
PHP 实现公历日期与农历日期的互转换
2017/09/13 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
基于Jquery实现的一个图片滚动切换
2012/06/21 Javascript
jQuery插件-jRating评分插件源码分析及使用方法
2012/12/28 Javascript
表单的焦点顺序tabindex和对应enter键提交
2013/01/04 Javascript
jquery实现固定顶部导航效果(仿蘑菇街)
2013/03/21 Javascript
JS实现图片横向滚动效果示例代码
2013/09/04 Javascript
jQuery仿360导航页图标拖动排序效果代码分享
2015/08/24 Javascript
JS实现仿QQ效果的三级竖向菜单
2015/09/25 Javascript
Node.js程序中的本地文件操作用法小结
2016/03/06 Javascript
关于JavaScript中事件绑定的方法总结
2016/10/26 Javascript
node.js文件上传处理示例
2016/10/27 Javascript
详解javascript立即执行函数表达式IIFE
2017/02/13 Javascript
无法获取隐藏元素宽度和高度的解决方案
2017/03/07 Javascript
Webpack性能优化 DLL 用法详解
2017/08/10 Javascript
js简单的分页器插件代码实例
2019/09/11 Javascript
Python下rrdtool模块的基本使用方法
2015/11/13 Python
基于Python中numpy数组的合并实例讲解
2018/04/04 Python
Python常用爬虫代码总结方便查询
2019/02/25 Python
Django框架实现分页显示内容的方法详解
2019/05/10 Python
python实现自动化上线脚本的示例
2019/07/01 Python
pygame实现俄罗斯方块游戏(基础篇1)
2019/10/29 Python
Python3如何对urllib和urllib2进行重构
2019/11/25 Python
python如何修改文件时间属性
2021/02/05 Python
分享全球十款超强HTML5开发工具
2014/05/14 HTML / CSS
英国美发和美容产品商城:HQhair
2019/02/08 全球购物
三项教育活动实施方案
2014/03/30 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
2019最新公司租房合同(例文)
2019/07/18 职场文书
李清照的诗词赏析(20首)
2019/08/22 职场文书
导游词之扬州大明寺
2019/10/09 职场文书
opencv深入浅出了解机器学习和深度学习
2022/03/17 Python
Win11使用CAD卡顿或者致命错误怎么办?Win11无法正常使用CAD的解决方法
2022/07/23 数码科技