跨域相关
跨域是前端开发中经常遇到的一个问题,主要是由于请求的源地址与目标地址不同源产生的问题。下面我们就深入的了解和学习一下有关跨域的那些事儿。
同源策略是什么鬼?和跨域有什么关系?
同源策略最早出现于1995年的网景浏览器,它限定了不同源脚本之间的访问权限,比如cookie等信息,保障了浏览器的安全性。比较官方、常见的解释有,
同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。--MDN
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。--百度百科
跨域又是什么呢?简单地说,跨域是指为了解决由于同源策略带来的限制,保证不同源脚本可以调用的一种概念。为了更好的解决同源限制,我们继续看同源策略。
同源策略的规则
怎么才算是同源呢?看规定
同源策略规定只有协议、域名、端口都一致的才算同源。
说道这些我们先来看一下这个URL源的组成。
一般的url都由以下几个部分组成:协议、域名、端口、路径、search、hash,如下图
根据上图及同源规则,以http://www.heioray.com/index.html为例,我们来看一下下面各个url与这个URL的同源情况
对比的URL | 结果 | 分析 |
---|---|---|
http://www.heioray.com/info2.html | 同源 | 协议、域名一致,http协议端口默认80一致 |
http://www.heioray.com/info2/other.html | 同源 | 同上 |
http://www.heioray.com:81/info/other.html | 不同源 | 端口不一致 |
https://www.heioray.com/info/other.html | 不同源 | 协议不一致 |
http://heioray.com/info/other.html | 不同源 | 一级域名一致,二级域名不一致 |
http://v2.www.heioray.com/info/other.html | 不同源 | 同上 |
同源策略都限制了什么?
首先从一个页面展现上来看,涉及到URL请求的通常包括以下几个部分
1、script、style标签
2、img、audio等资源文件
3、xml http请求
其中前两类同源策略是不限制的,唯一限制的就是最后一个。根据http请求头里面有一个referer属性,浏览器可以识别请求与目标是否同源,并进行限制。
解决方案
那针对同源策略,我们需要跨域时怎么办呢?
利用同源策略没有覆盖到的地方
1、这就是Jsonp的原理,但有一个缺点,JSONP只能发送get请求
2、cookie在同源策略中的限制并不完整,它允许一级域名一致的两个url,在设置一级域名为domain的情况下共享cookie
document.domain = 'example.com';
其次设置header
这种设置一般需要服务端支持,在服务端设置允许跨域的header属性
res.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT");
res.setHeader('Access-Control-Allow-Credentials', true);
cors本身在服务端也是这个原理
此外
1、对于frame插入
服务端在响应头里面有一个X-Frame-Options头属性,它限定了该页面是否可以被作为frame调用,而这个属性有三个值可选:
DENY:浏览器拒绝当前页面加载任何Frame页面
SAMEORIGIN:frame页面的地址只能为同源域名下的页面
ALLOW-FROM:允许frame加载的页面地址
2、node框架解决方案?
node下解决主要两个思路,
自己写。自己写无非就是设置header
用现有模块。npm上有一个叫cors的模块。在node主文件require进来,然后app.use()一下即可,简单便捷。