通信类

同源策略及限制

概念

同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。

举例

以下网页想要访问以下接口,是不可以的。因为它们的源是不一样的。
网页:http://www.yourname.com/page1.html
接口:http://m.imooc.com/course/ajaxcourserecom?cid=459
设身处地的想一想,人家辛辛苦苦地做了一个信息库接口,结果被别的网页直接拿去调用了,是不是很过分?所以浏览器一定要有同源策略,以保证这种事情不会发生。

什么是源和跨域

源包括三部分内容,协议,域名和端口。
比如https://www.imooc.com,其中https是协议,www.imooc.com是域名,端口是80(如果没有指定端口,默认就是80)。这三部分共同组成了源,其中有一部分不一样,那么源就不一样的,也就是我们所说的跨域

什么是限制

不是一个源的文档,没有权利去操作另一个源的文档。
主要体现在以下几个方面:

  • Cookie,LocalStorage和IndexDB无法读取
  • DOM无法获得
  • AJAX请求不能发送(AJAX只适合同源通信,跨域就不行了)
可以跨域的三个标签(比较特殊)
  • 图片加载:
    用于加载其他网站的图片
  • css加载:
    可以使用CDN,CDN也是其他域
  • script加载:
    • 分析
      首先,http://coding.m.imooc.com/api.js是我们引入的外部API,这个API的返回内容由服务端生成,格式如callback({x:100,y:200})
      然后,由于在JSONP中已经定义了window.callback,所以JS在运行到最后一行的的外部API引入时,会运行callback函数。callback函数里的参数(data)是我们想要的数据,通过这种方式就获取到了。

    • 缺陷
      首先,只能发送Get请求,复杂数据无法提交
      其次,返回的数据内容必须确保被JS正确执行

    跨域通信的方式2:XHR2.0的CORS跨域方案(前端 + 服务器端)
    • XMLHTTPRequest Level 2中加入的,属于XHR的高级功能
    • 需要服务器配合设置响应头
    • 可选择是否带上cookie

    CORS跨域方案中的前端请求,分为简单请求与复杂请求:

    1. 复杂请求会先发送一次OPTIONS方法的预检请求,而简单请求不需要预检
    2. 简单请求需要同时满足的条件:
      请求Method必须为HEAD,GET,POST之一
      请求头中的字段不超过Accept,Accept-Language,Content-Language,Last-Event-ID,Content-Type
      Content-Type只限于三个值application/x-www-form-urlencoded,multipart/form-data,text/plain

    设置设置响应头(服务器端)

    // 注意:不同后端语言的写法可能不一样
    
    response.setHeader('Access-Control-Allow-Origin', 'http://a.com,http://b.com');
    // 表示允许访问的域名,只允许设置一个。如果想设置多个,需要后端设置白名单并做判断。
    // 必须在响应头中设置该字段
    // 可使用 * 表示允许任意域名,但是不建议这么做
    
    response.setHeader('Access-Control-Allow-Credentials','true');
    // 值设置为true,表示允许向服务器发送cookie
    // 客户端需要设置XHR对象的withCredentials为true
    // Access-Control-Allow-Origin必须设置为指定域名,* 是不行的。
    
    response.setHeader('Access-Control-Expose-Headers', 'Data');  // 允许客户端获取Data
    // 表示允许客户端通过getResponseHeader方法获取的字段
    // CORS方式下该方法默认只能获取6个基础字段
    // Cache-Control,Expires,Content-Language
    // Last-Modified,Content-type,Pragma
    
    
    response.setHeader('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS');
    // 表示服务端接受的跨域请求方法
    // 多个方法用逗号分隔,使用 * 号表示任意方法
    // 必须在预检响应头中设置该字段
    
    response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With');
    // 表示服务端接受的跨域请求的字段
    // 多个字段名用逗号分隔
    // 请求头含Access-Control-Request-Headers时为必须
    
    response.setHeader('Access-Control-Max-Age', '');
    // 表示缓存预检结果
    // 以秒为单位
    // 在此期间不再发送预检请求
    

你可能感兴趣的:(通信类)