浏览器-同源策略 跨域的解决方式

378 阅读2分钟

1.同源策略

1.1 同源策略的含义

同源需要同时满足协议 域名 端口号三个条件一模一样才行,缺一不可,举例不满足同源如下

http: www.baidu.com 与 https: www.baidu.com 协议不同

http: www.baidu.com 与 https: www.wangyi.com 域名不同

http: www.baidu.com:80 与 https: www.baidu.com:88 端口不同

1.3同源策略的目的

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

1.4同源政策的限制范围

cookie, LocalStorage 和 IndexDB 无法读取

dom无法获取

ajax请求不能发送

解决同源策略常用方法

1 一级域名情况相同, 二级域名不同的情况 例如a.test.com与b.test.com

这种场景可以设置document.domain = test.com;

这时候a.test.com与b.test.com cookie可以共享

2 window.postmessage跨窗口调用信息 eg:
 <iframe src="127.0.0.1:80001" id="iframe"></iframe>

获取 iframe的window对象

 const iframeWindow = document.getElementById('iframe').contentWindow;

然后给iframe的window发送消息

 iframeWindow.postmessage({a:1,b:2}, 127.0.0.1:8000)

然后在iframe中监听消息

 window.addEventListener('message', (e) => console.log(e.data), false)

 这样两个窗口之间都能互相通信了

3 ajax跨域解决方法

3.1 jsonp
jsonp的原理 利用script的src不需要同源的漏洞像服务器发起一次请求 服务器返回一段可执行的js函数 服务器想返回的json数据作为返回函数的参数 这样客户端只要定义了该函数 就能拿到服务器返回的数据 封装一段简易的jsonp
  const jsonp = (url, params = {}, callback = 'jsonpCallback') => {
   const srcipt = document.createElement('script');
   const paramsArray= Object.keys(params).map(key => `${key}=${params[key]}`) || [];
   paramsArray.push(`callback=jsonpCallback`);
   const urlParamsString = paramsArray.join("&")
   srcipt.async = true;
   script.type = 'text/javascript'
   srcipt.src = `${url}?${urlParamsString}`;
   window[callback] = (data => {
     //  这里拿到服务器返回的数据
     console.log(data);
   })
   document.body.appendChild(srcipt);
 }

3.2. cors

CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。

浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。

服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。

3.2. nginx代理 node服务代理

因为同源是针对客户端 对服务器没有任何限制 我们可以先代理到一个同源服务器上 在通过代理服务器去请求真正的服务哦