3

在日常的项目开发时会不可避免的需要进行跨域操作,面试中也是频繁被经常会问到的问题,本文只是我经常用到的解决跨域的方式做个记录与总结。

所有支持Javascript的 浏览器 都会使用‘同源策略’这个安全策略,所谓同源是指,域名,协议,端口相同,就是因为同源策略的影响导致没法直接用XMLHttpRequest请求不同域上的数据,所以各种解决问题的技术出现了。

Jsonp

<script> 标签元素是不受同源策略影响,OK,利用这一个漏洞,可以实现加载不同域服务器上的脚本啦。该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
以jquery封装的$.getJson()为例:

<script type="text/javascript">
    $.ajax({
             type: "get",
             url: "http://www.test.com?name='test'",
             dataType: "jsonp", 
             jsonpCallback:"callbackFun",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
             success: function(json){
                 alert('success');
             },
             error: function(){
                 alert('fail');
             }
         });
     });
</script>

通过dataType指定jsonp,jquery底层封装后,会在head标签后面追加<script src="http://www.test.com?name='test'&callback=callbackFun"></script>

所有的jsonP都是这个原理,借助script标签的跨域特性来实现,callbackFun再jquery中是自动生成的,后台会获取jsoncallback参数,获取对应的函数名称,最后包装成想要的格式,比如最后输出结果是:callbackFun({"result":"suc","code":"1000"}),那么再Jquery中,会将该方法直接指定给success方法,最后来接收返回的数据。

JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

cors

CROS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CROS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
前端实现方式和一般的ajax请求是一样的,只是方式的接口是绝对地址。服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

服务器代理

禁止跨域问题其实是浏览器的一种安全行为,假如我们的目标服务器不能设置header,而且我们需要发送post请求,上面的解决方案就被否定了,但是服务器与服务器之间的请求是不存在跨域的。

强大的nginx,伟大的nodeJS都可以实现一个代理服务器功能。

反向代理服务器,就是把http请求转发到另一个或者一些服务器上。通过把本地一个url前缀映射到要跨域访问的web服务器上,就可以实现跨域访问。对于浏览器来说,访问的就是同源服务器上的一个url。而nginx通过检测url前缀,把http请求转发到后面真实的物理服务器。并通过rewrite命令把前缀再去掉。这样真实的服务器就可以正确处理请求,并且并不知道这个请求是来自代理服务器的。

nginx的配置方法网上已经泛滥了,保存几个参考过的网址。
http://www.imooc.com/article/...
http://www.cnblogs.com/renjin...
http://www.cnblogs.com/bninp/...

nodeJs 主要是使用的node-http-proxy实现的,相关信息也很多。
https://github.com/nodejitsu/...
http://www.cnblogs.com/woodk/...
http://blog.csdn.net/jaye100/...


泽浩沉
288 声望18 粉丝

希望自己能够自由地对各种事情发表自己的意见


« 上一篇
hapi 起步