本文主要是介绍【taotao】JS跨域,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【跨域概述】
在JS中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略)。这一策略对于JS代码
能够访问的页面内容做了很重要的限制,即JS只能访问与包含它的文档在同一域下的内容。因此,也产生了跨域的概
念。
【什么是跨域】
JS为了安全,有一个限制,不允许跨域访问。
1. 两个url的域名不同
2. url相同,域名不同或端口不同
3. ip不同
以上三种情况,都属于跨域。
【跨域场景】
1. 场景描述
两个工程:
服务层:taotao-rest:没有表现层,只有业务逻辑。需要发布服务。部署在8081端口
表现层:taotao-portal:只有表现层,没有业务逻辑,不需要连接数据库。部署在8082端口
表现层和服务层通信,使用Webservice进行通信。Restful形式的Webservice。http+json数据。
2. 场景再现
现需要展示所有商品类目信息,以静态的json数据为例,若该数据在portal项目中,js代码如下:
//访问地址
URL_Serv: "http://localhost:8082/category.json"
商品类目展示是没有问题的,
而如果将该json数据放在rest项目中,再通过修改URL_Serv的地址:
http://localhost:8081/category.json
这样便不能正常显示数据了,浏览器错误如下:
这就产生了本篇博客要说的跨域问题。下面来看,我们应该如何解决跨域问题。
【解决方案】
jsonp
首先我们需要明确,在js中不能跨域请求数据,js可以跨域请求js片段。所以,我们可以将数据包装成js片
段,形成一条方法的调用语句,继续使用ajax请求js片段,得到响应后,在浏览器端的回调方法中通过参数获得请求
的数据。过程如下:
这样我们可以将以上的代码修改为:
//访问地址,URL_Serv:
再访问首页商品类目:
【JSONP的产生】
1. 首先我们应该知道,在web页面上调用js文件则不受是否跨域的影响,而且拥有src属性的标签,如
<script>/<img>/<iframe>,都拥有跨域的能力;
2. 所以,要是想通过纯web端跨域访问数据只有一种可能,那就是设法把数据装进js文件里,供客户端调用
和进一步的处理;
3. 恰巧JSON数据格式可以简单地描述复杂数据,而且被JSON支持,所以在客户端便可以任意处理此格式的
数据;
4. 因此,解决方案就出现了:web端通过调用与脚本一样的方式,去调用跨域服务器上动态生成的js文件
(一般以JSON为后缀)
5. 客户端在对JSON文件调用成功之后,便获取到了自己所需要的数据,剩下的便可以按照自己的需求去展
示了。
6. 为了便于客户端使用数据,逐渐形成了一种非正式传输协议,便是JSONP。
【关于JSONP的几个问题】
1. jsonp跨域只能是get请求,而不能是post请求?
2. jsonp跨域的原理到底是什么?
3. 除了jsonp跨域之外还有那些方法绕过“同源策略”,实现跨域访问?
4. jsonp和ajax,或者说jsonp和XMLHttpRequest是什么关系?
下面就从jsonp跨域原理说起。
1、JSONP的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。
2、由第1点,这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了。在没有ajax技术之前,
script标签就存在了的。是因为JQuery的封装,使用了ajax来向服务器传递jsonp和jsonpCallback两个参数。
3、script,link,img等等标签引入外部资源,都是get请求,那么就决定了jsonp一定是get。但其实上在
代码中写post请求也能成功。这是因为当我们指定dataType:'jsonp',不论指定type:'post'或type:'get',其实质
上都是get请求。
对应的jquery源码如下:
// Handle cache's special case and global
jQuery.ajaxPrefilter( "script", function( s ) {if ( s.cache === undefined ) {s.cache = false;}if ( s.crossDomain ) {s.type = "GET";s.global = false;}
});
在ajax的过滤函数中,只要是跨域,jQuery就将其type设置成"GET".
4、其实除了jsonp跨域之外,还有其它方法绕过同源策略。因为同源是针对客户端的,在服务器端是可以随
便访问的。所以我们可以通过客户端先访问同源的服务端代码,该同源的服务端代码,使用httpClient等方法,再去
访问不同源的服务端代码,然后将结果返回给客户端,这样就实现了跨域。
5、参数jsonp和jsonCallback
jsonp指定使用哪个名字将回调函数传给服务端,也就是在服务端通过request.getParameter("")获得的名
字,而jsonpCallback是对应的值,也就是回调函数的名称。其实这两个参数都可以不指定,只要我们是通过
success,来指定回调函数的情况下,默认就是“callback”。JQuery对应源码如下:
var oldCallbacks = [],rjsonp = /(=)\?(?=&|$)|\?\?/;// Default jsonp settings
jQuery.ajaxSetup({jsonp: "callback",jsonpCallback: function() {var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );this[ callback ] = true;return callback;}
});
【总结】
跨域,经常会遇到的问题。之前的学习还没有到此阶段,所以总是选择避免这样的问题。而现在,学习积累
到了一定阶段,就有了第一次的接触,学习到了其中的一种解决方案jsonp。从遇到的问题出发,到给出解决方案,
这一过程的学习很充实。并且,解决的方案并不仅仅有jsonp哦。
这篇关于【taotao】JS跨域的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!