总结前端跨域解决方案
什么是同源策略
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
同源策略限制以下几种行为:
- IndexDB、LocalStorage 和 Cookie无法读取
- Js对象 和DOM无法获得
- AJAX 请求不能发送
同源需要:(<img><link><script>
三种标签不受限制)
我们可以根据同源策略的定义,总结出常见的6种跨域场景:
遇到上述这些情况,根据我们应用的技术,我们可以总结出来9种跨域解决方案:
实现跨域的常用方式
通过jsonp跨域
利用<script>
标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。优点是兼容老式浏览器,但是只支持get而且不太安全,一般不用。基于此原理,我们可以通过动态去创建script
,再请求一个带参网址实现跨域通信。
jsonp缺点:只能实现get一种请求。
var script = document.createElement("script");
script.type = "text/javascript";
//传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src =
"http://www.baidu.com:8080/login?user=admin&callback=handleCallback";
document.head.appendChild(script);
//回调执行函数
function handleCallback(res) {
console.log("res =", res);
}
CORS跨域
跨域的请求其实是发出去了的,只不过被浏览器给拦截了,因为不安全,说直白点儿就是,你想要从服务器哪儿拿个东西,但是没有经过人家允许啊。所以怎么样才安全 ?服务器允许了不就安全了,这就是 CORS 实现的原理:使用额外的 HTTP 头来告诉浏览器,让运行在某一个 origin 上的 Web 应用允许访问来自不同源服务器上的指定的资源。
目前,所有的主流浏览器都支持 CORS,其中,IE 浏览器的版本不能低于 10,IE 8 和 9 需要通过 XDomainRequest 来实现。
简单请求
若请求满足所有下述条件,则该请求可视为“简单请求”:
允许的方法之一:
Fetch 规范定义了对 CORS 安全的首部字段集合
不得人为设置该集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type
(需要注意额外的限制)DPR
Downlink
Save-Data
Viewport-Width
Width
Content-Typ
的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
预检请求
与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS
方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
Websocket
WebSocket 规范定义了一种 API,可在网络浏览器和服务器之间建立“套接字”连接。简单地说:客户端和服务器之间存在持久的连接,而且双方都可以随时开始发送数据。
这种方式本质没有使用了 HTTP 的响应头, 因此也没有跨域的限制
前端部分
let socket = new WebSocket("ws://localhost:8080");
socket.onopen = function() {
socket.send("秋风的笔记");
};
socket.onmessage = function(e) {
console.log(e.data);
};
window.postMessage
window.postMessage()
方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口号(443 为 https 的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage()
方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。
用途
1.页面和其打开的新窗口的数据传递
2.多窗口之间消息传递
3.页面与嵌套的 iframe 消息传递
node中间件代理
实现原理: 同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略。代理服务器,需要做以下几个步骤:
- 接受客户端请求
- 将请求转发给服务器
- 拿到服务器响应数据
- 将响应转发给客户端