zoukankan      html  css  js  c++  java
  • 同源策略、跨域、json和jsonp

    同源策略

    源(origin)就是协议、域名和端口号。若地址里面的协议、域名和端口号均相同则属于同源。

    以下是相对于 http://www.a.com/test/index.html 的同源检测
      • http://www.a.com/dir/page.html ----成功
      • http://www.child.a.com/test/index.html ----失败,域名不同
      • https://www.a.com/test/index.html ----失败,协议不同
      • http://www.a.com:8080/test/index.html ----失败,端口号不同

    同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。

    跨域

    1、什么是跨域

    受前面所讲的浏览器同源策略的影响,不是同源的脚本不能操作其他源下面的对象。想要操作另一个源下的对象是就需要跨域。

    2、跨域的实现方式

    (1)降域 document.domain

    同源策略认为域和子域属于不同的域,如:child1.a.com 与 a.com,child1.a.com 与 child2.a.com,xxx.child1.a.com 与 child1.a.com

    两两不同源,可以通过设置 document.damain='a.com',浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.damain='a.com'。

    此方式的特点:

    1.  只能在父域名与子域名之间使用,且将 xxx.child1.a.com域名设置为a.com后,不能再设置成child1.a.com
    2. 存在安全性问题,当一个站点被攻击后,另一个站点会引起安全漏洞。
    3. 这种方法只适用于 Cookie 和 iframe 窗口。

    (2)JSONP跨域

    采用jsonp跨域也存在问题:

    1. 使用这种方法,只要是个网站都可以拿到b.com里的数据,存在安全性问题。需要网站双方商议基础token的身份验证。
    2. 只能是GET,不能POST。
    3.  可能被注入恶意代码,篡改页面内容,可以采用字符串过滤来规避此问题。

    (3)CORS

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。刚才的例子中,在b.com里面添加响应头声明允许a.com的访问,代码:Access-Control-Allow-Origin: http://a.com然后a.com就可以用ajax获取b.com里的数据了。

    (4)其它方法

    1. HTML5的postMessage方法
    2. window.name
    3. location.hash

    json和jsonp

    • JSON是一种基于文本的数据交换方式(不支持跨域),或者叫做数据描述格式,是数组和对象的嵌套,而JSONP是一种非官方跨域数据交互协议。简单地使用json并不能支持跨域资源请求,为了解决这个问题,需要采用jsonp数据交互协议。
    • 同源下的前后端数据交换格式确定使用json了,如果想获取别人网站上提供的数据怎么做到呢?也就是跨域读取数据问题,json是不行的,因为json只是普通的文本格式,能让你这样就轻松拿到那服务端就没有任何安全和保密性可言了,所以浏览器使用了同源策略来限制文件获取。最后的结果就是只有像img、script、iframe这类可以指定src属性的标签有跨域获取别人网站上数据(图片,脚本,源文件其实都是数据)的能力。比如:
      <img src="http://img30.360buyimg.com/jgsq-productsoa/jfs/t2407/323/1635505465/47386/f2d89d88/56615e00N7a475ee6.jpg" />
      
      <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    • 然而,众所周知,js文件的调用不受跨域与否的限制,因此如果想通过纯web端跨域访问数据,只能在远程服务器上设法将json数据封装进js格式的文件中,供客户端调用和进一步处理,这就是jsonp协议的原理。该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了
    • 简单的说,就是json不支持跨域,而js可以跨域,因此在服务器端用客户端提供的js函数名将json数据封装起来,再将函数提供给客户端调用,从而获得json数据。开发过程中,如果出现类似 “Origin ****** is not allowed by Access-Control-Allow-Origin.” 的错误,则可能是由于json数据不支持跨域导致的,应考虑使用jsonp协议。如果出现类似 ”SyntaxError: Unexpected token ':'. Parse error.“ 的错误,则可能是由于返回的json数据没有用”callback“传递的函数名封装导致的。

      例如:网站A需要获取网站B的数据,网站B说我给你们一个方法:

      1. 你们使用<script src="http://www.B.com/open.js"></script>标签先获取到open.js文件(网站B的责任),这里边有你们需要的数据。

      2. 你们获取数据后处理数据的方法名必须命名为foo(数据请求者的责任和义务)

      这里相当于B网站和请求获取数据者之间建立了一个协议,要求请求者务必按照规则办事,如果请求者不能同时遵守上面两条就不能按预期获取数据。

    • jsonp全名叫做json with padding,很形象,就是把json对象用符合js语法的形式包裹起来以使其它网站可以请求得到,也就是将json数据封装成js文件;
    • json是理想的数据交换格式,但没办法跨域直接获取,于是就将json包裹(padding)在一个合法的js语句中作为js文件传过去。这就是json和jsonp的区别,json是想要的东西,jsonp是达到这个目的而普遍采用的一种方法,当然最终获得和处理的还是json。所以说json是目的,jsonp只是手段。json总会用到,而jsonp只有在跨域获取数据才会用到。
    • 理解了json和jsonp的区别之后,其实ajax里的跨域获取数据就很好理解和实现了,同源时候并没有什么特别的,直接取就行,跨域时候需要拐个弯来达到目的。
    • 附上jquery中ajax请求json数据实例:
      //同源
      $.ajax({
          url:"persons.json",
          success:function(data){
      console.log(data);
       //ToDo..
      }
      });
      
      //跨域
      $.ajax({
          url:"http://www.B.com/open.php?callback=?",
          dataType:"jsonp",
          success:function(data){
              console.log(data);
              //ToDo..
          }
      }); 
  • 相关阅读:
    第一节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表、验证码表、轮播图表
    Tensorflow 错误:Unknown command line flag 'f'
    Python 多线程总结
    Git 强制拉取覆盖本地所有文件
    Hive常用函数 傻瓜学习笔记 附完整示例
    Linux 删除指定大小(范围)的文件
    Python 操作 HBase —— Trift Trift2 Happybase 安装使用
    梯度消失 梯度爆炸 梯度偏置 梯度饱和 梯度死亡 文献收藏
    Embedding 文献收藏
    深度学习在CTR预估中的应用 文献收藏
  • 原文地址:https://www.cnblogs.com/lmjZone/p/8508190.html
Copyright © 2011-2022 走看看