跨域

171 阅读2分钟

知识框架

  • 同源策略
    • 浏览器故意设计的一个功能限制
  • CORS
    • 突破浏览器限制的一个方法
  • JSONP
    • IE时代的妥协

同源策略

同源定义

    • window.origin或者local.origin可以得到的当前源
    • 源=协议+域名+端口号
  • 如果两个url的
    • 协议
    • 域名
    • 端口号
    • 完全一直,那么两个url就是同源
  • 举例
  • qq.comwwww.baidu.com 不同源
  • baidu.comwwww.baidu.com 不同源
  • 必须完全一致

同源策略定义

不同源的页面之间,不准互相访问数据

  • 浏览器规定
    • 如果JS运行在源A里面,那么就值呢个获取源A的数据
    • 不能获取源B的数据,即不允许跨域

目的

  • 为了保护隐私

保护机制

  • 以qq空间为例
    • 源为user.qzone.qq.com
    • 假设当前用户已经登录
    • AJAX请求/friends.json可获取好友列表
  • 如果没有同源策略
    • 一个钓鱼网站 qzone-qq.com
    • 点开网页请求好友列表,就可以把/freinds.json偷走

问题的根源

  • 无法区分发送者
  • 发送的请求几乎没有区别(refer有区别)
  • 如果后台开发者没有检查refer,那就完全没有区别
  • 所以浏览器为了用户隐私,设置了严格的同源策略

问题:为什么可以跨域访问到CSS,JS和图片等

  • 同源策略限制的是数据访问,我们引用CSS、JS和图片的时候,只是在引用,并不知道其内容(可以使用,但是得不到里面的数据)

如何实现跨域?

方法一:CORS(跨域资源共享)

  • 问题根源
    • 浏览器默认不同源之间不能互相访问数据
  • 用CORS解决
  • 浏览器规定,如果要共享数据,需提前声明
  • 在某个网站的响应头里面写明某个源可以访问
  • Access-Control-Alllow-Origin : foo.example
  • 具体设置如下:
    • 在被请求源的服务器里面设置 1635228014(1).png
  • 具体用法:developer.mozilla.org/zh-CN/docs/…

方法二:JSONP(IE兼容会用到)

  • 背景:在跨域的时候,由于浏览器不支持不支持CORS(或者处于某种原因不支持CORS),必须使用其他方式实现跨域
  • 于是请求一个JS文件,这个文件会执行一个回调,回调里面就有所需要的数据
  • 回调的名称是个随机数,可以把这个名称以Callback的参数传给后台,后台把这个函数返回给用户并执行
  • 优缺点:兼容IE,实现跨域,最大的优点
  • 缺点
    • 由于它是<script标签,无法像AJAX准确地知道状态码,得不到头文件,只能判断成功和失败
    • 由于它是script标签,只能发送GET请求,不支持post(script本身就不支持post)

补充

  • postmassage不是用来跨域的,是实现网页端通信的