跳到主要内容

跨域

跨域是浏览器的同源策略带来的,浏览器单方面拒绝请求。

同源策略

同源策略是浏览器的一个重要的安全策略,限制不同源之间的交互,从而能够有效避免XSS、CSFR等浏览器层面的攻击。

XSS

Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。

CSFR

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

解决方案

jsonp

最早的解决方案之一,实现方式是通过script标签传递数据,因为script请求不会被同源策略禁止,所以通过script标签去请求跨域数据,并且在script的callback对饮function中实现对数据的获取。

CORS

跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求

简单请求:某些不会触发CORS预检的请求

  1. 设置不会触发预检的Methods:GET\HEAD\POST。HEAD就是指发送请求不会收到响应的一种请求方式
  2. 简单请求可以只设置header如下Accept、Accept-Language、Content-Language、Content-Type
  3. Content-Type标头允许的值只能是application/x-www-form-urlencoded、 multipart/form-data、 text/plain

后端适配方案:在respones header中添加Access-Control-Allow-Origin

 Access-Control-Allow-Origin代表允许发送请求的源,参数可以是固定的白名单ip或者通配符,可以用通配符"*",代表接受所有请求。不过有种特殊情况是不能使用通配符的,就是前端请求header中含有withCredentials,withCredentials:true是跨域请求想要携带cookie必须加入的headers配置

复杂请求

预检请求就是在跨域的时候设置了对应的需要预检的内容,结果上会在普通跨域请求前添加了个options请求,用来检查前端header的修改是否在后端允许范围内。触发预检请求在跨域开发中会碰到的主要情况如下

  1. 首先设置methods设置为PUT、DELETE、CONNECT、OPTIONS、TRACE会导致预检请求
  2. 设置了Accept、Accept-Language、Content-Language、Conten-Type之外的header中任一的配置,比如常见的token:authorization,缓存机制cache-control
  3. Conten-Type设置了简单请求不允许的值必去application/json

操作预检请求就需要后端设置更多的respones headers如下

  1. Access-Control-Allow-Origin代表可接受的源
  2. Access-Control-Allow-Methods代表可接受的方法
  3. Access-control-Allow-Headers代表可接受的headers修改
  4. Access-Control-Max-age代表预检的残留时间,免预检的时间

实现CORS

  1. 本地代理
  2. nodejs中间件
  3. nginx代理

对比

jsonp和cors,两者优劣如下

  1. json只支持get请求,无法支持复杂的请求
  2. jsonp出现错误的时候,很难去进行错误识别与处理,cors可以正常错误捕捉
  3. jsonp的兼容性比较高,而cors在旧版ie中需要寻找对应的替代方案