zoukankan      html  css  js  c++  java
  • 同源策略和跨域-总结

    目录:
    1.同源策略
    2.跨域
    3.几种跨域技术 - JSONP, CORS
     

     
    1.同源策略
    什么叫同源?
    URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。相反,只要协议,域名,端口有任何一个的不同,就被当作是跨域。
    e.g. 对于http://store.company.com/dir/page.html进行同源检测:
    URL结果原因
    http://store.company.com/dir2/other.html 成功 仅路径不同
    http://store.company.com/dir/inner/another.html 成功 仅路径不同 
    https://store.company.com/secure.html 失败 协议不同
    http://store.company.com:81/dir/etc.html 失败 端口不同
    http://news.company.com/dir/other.html 失败 主机名不同
     
    同源策略  Same-Origin-Policy(SOP)
    浏览器采用同源策略,禁止页面加载或执行与自身来源不同的域的任何脚本。换句话说浏览器禁止的是来自不同源的"document"或脚本,对当前"document"读取或设置某些属性。
    情景:
    比如一个恶意网站的页面通过iframe嵌入了银行的登录页面(二者不同源),如果没有同源限制,恶意网页上的javascript脚本就可以在用户登录银行的时候获取用户名和密码。
     
    浏览器中有哪些不受同源限制呢?
    <script>、<img>、<iframe>、<link>这些包含 src 属性的标签可以加载跨域资源。但浏览器限制了JavaScript的权限使其不能读、写加载的内容。
     

     
    2.跨域
    跨域是指从一个域的网页去请求另一个域的资源。比如从http://www.baidu.com/ 页面去请求 http://www.google.com 的资源。
     

     
    3.跨域技术-JSONP
    JSONP是什么?
    上面提到过包含src属性的<script>标签可以加载跨域资源。 JSONP就是利用<script>标签的跨域能力实现跨域数据的访问。
     
    JSONP实现的原理
    在这之前,先来介绍下我是如何简单的开启服务的。
    使用python的SimpleHTTPServer模块(2.x)(3.x中时http.server)The SimpleHTTPServer module has been merged into http.server in Python 3.0.
    ------------------------------------------------------------------------------------------------
    如果你已经用过python,请跳过这里。
     
    >>安装python(注意设置环境变量 Path -- D:Program FilesPython2.7.1;)
    (验证python安装配置完成:打开cmd, 输入python 有识别)
    (cmd 切换工作目录)
    >>在工作目录中执行
    $ python -m SimpleHTTPServer 8088 (2.x)
    $ python -m http.server 8088 (3.x)
    >>服务启动后,不要关闭该窗口;否则相当于杀死了该服务进程
     
    ------------------------------------------------我是分割线---------------------------------------
    index.html,在8088端口提供服务
     1 <!doctype html>
     2 <html lang="en" ng-app="simpleApp">
     3 <head>
     4     <meta charset="UTF-8">
     5     <script src="scripts/vendor/angular.min.js"></script>
     6     <script src="scripts/vendor/angular-resource.min.js"></script>
     7     <script src="scripts/controllers/controllers.js"></script>
     8     <script src="scripts/services/services.js"></script>
     9     <link href="styles/bootstrap.css" rel="stylesheet">
    10 
    11     <!-- [跨域]step1. 通过拥有src属性的标签进行跨域调用 <script><img><iframe> -->
    12     <script type="text/javascript" src="http://localhost:8090/remote.js"></script>
    13 
    14     <!-- [跨域]step2. 本地函数被跨域的远程js调用,并接收远程js带来的数据 -->
    15     <script type="text/javascript">
    16         var localHandler = function(data){
    17             alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
    18         };
    19     </script>
    20 
    21     <!-- [跨域]step3. JSONP client端的核心:实现动态查询
    22         怎么样让远程JS知道它应该调用的本地函数叫什么名字?
    23         client传参告诉server"我想要一段调用xx函数的JS代码,请返回给我";即client在发送请求URL时,指定回调函数-->
    24     <script type="text/javascript">
    25         // 得到航班信息查询结果后的回调函数
    26         var flightHandler = function(data){
    27             <!-- [跨域]step4. 处理server返回的数据:几种格式 -->
    28             /* JSONArray
    29              * flightHandler([
    30              * {"code": "CA1998", "price": 1780, "tickets": 5 },
    31              * {"code": "CA2001", "price": 2090, "tickets": 10 }
    32              * ]);*/
    33             for(var i=0; i<data.length; i++){
    34                 alert('你查询的航班结果是:票价 ' + data[i].price + ' 元,' + '余票 ' + data[i].tickets + ' 张。');
    35             }
    36 
    37             /* JSON
    38              flightHandler({ "code": "CA1998", "price": 1780, "tickets": 5 });
    39              */
    40 //            alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    41         };
    42         // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    43         var url = "http://localhost:8090/remote.js?code=CA1998&callback=flightHandler";
    44         // 创建script标签,设置其属性
    45         var script = document.createElement('script');
    46         script.setAttribute('src', url);
    47         // 把script标签加入head,此时调用开始
    48         document.getElementsByTagName('head')[0].appendChild(script);
    49     </script>
    50     
    51     <title>simpleApp</title>
    52 </head>
    53 <body>
    54     <div ng-view></div>
    55 </body>
    56 </html>
    View Code

    remote.js,在8090端口提供服务,来模拟不同域的远程文件(端口不同)

     1 alert("远程文件");
     2 localHandler({"result":"我是远程js带来的数据"});
     3 
     4 //JSON
     5 flightHandler({
     6     "code": "CA1998",
     7     "price": 1780,
     8     "tickets": 5
     9 });
    10 
    11 //JSONArray
    12 flightHandler([{
    13     "code": "CA1998",
    14     "price": 1780,
    15     "tickets": 5
    16 }, {
    17     "code": "CA2001",
    18     "price": 2090,
    19     "tickets": 10
    20 }]);
    View Code
     
    JSONP的缺点
    JSONP只支持 GET 请求。
     
    支持JSONP的不同技术
    >>AngularJS
    1 myUrl ="http://localhost:8090/api/test?callback=JSON_CALLBACK";
    2 $http.jsonp(myUrl).success(
    3      function(data){
    4           alert(data);
    5      }     
    6 );
    1.angularJS中使用$http.jsonp函数
    2.指定callback和回调函数名,函数名为JSON_CALLBACK时,会调用success回调函数,JSON_CALLBACK必须全为大写。
    3.也可以指定其它回调函数,但必须是定义在window下的全局函数。
    4.url中必须加上callback
    5.当callback为JSON_CALLBACK时,只会调用success,即使window中有JSON_CALLBACK函数,也不会调用该函数。
     
    >>Ajax
     1 myUrl ="http://localhost:8090/api/test";
     2 $.ajax({
     3   type:"GET",
     4   url:myUrl,
     5   dataType:"jsonp",
     6   jsonp:"callback",
     7   jsonpCallback:"jsonpCallback",
     8   success:function(data){
     9     alert(data.msg);
    10   }
    11 });
    12 function jsonpCallback(data){
    13      alert(data);
    14 }
    JSONP 是通过动态添加<script>标签来调用服务器的脚本(<script>含有src属性,src属性没有跨域限制);而 Ajax 是通过 XHR(XmlHttpRequest) 对象。两者并没有直接关系,以上只是Ajax封装JSONP的一种方式。
     

     
    4.跨域技术-CORS (CrossOrigin Resources Sharing,跨源资源共享)
    CORS是什么?
    CORS,是 HTML5 的一项特性,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。
    相对于 JSONP 这种解决方案来说,使用CORS,不需要要求服务器以指定格式返回数据(包装成JS脚本的格式:callback_func({ data }););CORS,只需要在服务器端做一些通用设置。
     
    一个简单有效的解决方案:SpringMvc+AngularJS通过CORS实现跨域方案

    参考网站:
    enable cross-origin resource sharing 对各种服务器设置的详细介绍,主流浏览器支持一览。
     
     
     
  • 相关阅读:
    天气渐凉,意渐浓
    WebBrowser 多线程 DocumentCompleted 和定时器
    浅谈 Glide
    浅谈 maxMemory , totalMemory , freeMemory 和 OOM 与 native Heap
    XGoServer 一个基础性、模块完整且安全可靠的服务端框架
    GreenDao 兼容升级,保留旧数据的---全方面解决方案
    基于 xorm 的服务端框架 XGoServer
    全面总结: Golang 调用 C/C++,例子式教程
    通俗易懂,各常用线程池的执行 流程图
    为什么我的子线程更新了 UI 没报错?借此,纠正一些Android 程序员的一个知识误区
  • 原文地址:https://www.cnblogs.com/xhz-dalalala/p/5259965.html
Copyright © 2011-2022 走看看