跨域
跨域是浏览器的同源策略带来的,浏览器单方面拒绝请求。
同源策略
同源策略是浏览器的一个重要的安全策略,限制不同源之间的交互,从而能够有效避免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预检的请求
- 设置不会触发预检的Methods:GET\HEAD\POST。HEAD就是指发送请求不会收到响应的一种请求方式
- 简单请求可以只设置header如下Accept、Accept-Language、Content-Language、Content-Type
- 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的修改是否在后端允许范围内。触发预检请求在跨域开发中会碰到的主要情况如下
- 首先设置methods设置为PUT、DELETE、CONNECT、OPTIONS、TRACE会导致预检请求
- 设置了Accept、Accept-Language、Content-Language、Conten-Type之外的header中任一的配置,比如常见的token:authorization,缓存机制cache-control
- Conten-Type设置了简单请求不允许的值必去application/json
操作预检请求就需要后端设置更多的respones headers如下
- Access-Control-Allow-Origin代表可接受的源
- Access-Control-Allow-Methods代表可接受的方法
- Access-control-Allow-Headers代表可接受的headers修改
- Access-Control-Max-age代表预检的残留时间,免预检的时间
实现CORS
- 本地代理
- nodejs中间件
- nginx代理
对比
jsonp和cors,两者优劣如下
- json只支持get请求,无法支持复杂的请求
- jsonp出现错误的时候,很难去进行错误识别与处理,cors可以正常错误捕捉
- jsonp的兼容性比较高,而cors在旧版ie中需要寻找对应的替代方案