跨域

一、为什么会出现跨域问题

出于浏览器的同源策略限制。同源策略,所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port),当你需要跨域请求服务的时候就会出现跨域请求问题(浏览器为了上网安全架起同源策略)
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
在这里插入图片描述

二、非同源限制(简单地说你跨域请求会失败,并调用不到资源)

【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

【2】无法接触非同源网页的 DOM

【3】无法向非同源地址发送 AJAX 请求

三、解决方法(后端代理或者接口CORS(跨域资源共享))

JSONP跨域(不安全)

JSONP(JSON with Padding)是数据格式 JSON 的一种“使用模式”,可以让网页从别的网域要数据。根据 XmlHttpRequest 对象受到同源策略的影响,而利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的JSON数据,而这种使用模式就是所谓的 JSONP。用JSONP抓到的数据并不是JSON,而是任意的JavaScript,用 JavaScript解释器运行而不是用JSON解析器解析。所有,通过Chrome查看所有JSONP发送的Get请求都是js类型,而非 XHR。

缺点:
只能使用Get请求
不能注册 success、error 等事件监听函数,不能很容易的确定 JSONP 请求是否失败
JSONP 是从其他域中加载代码执行,容易受到跨站请求伪造的攻击,其安全性无法确保

或者使用

window.name+iframe(耗损性能)

iframe一般用来包含别的页面,例如我们可以在我们自己的网站页面加载别人网站的内容,为了更好的效果,可能需要使iframe透明效果,那么就需要了解更多的iframe属性。
window.name通过在iframe(一般动态创建)中加载跨域HTML文件来起作用。然后,HTML文件将传递给请求者的字符串内容赋值给window.name。然后,请求者可以检索window.name值作为响应。

iframe 标签的跨域能力;
window.name 属性值在文档刷新后依旧存在的能力(且最大允许2M左右)。
每个 iframe 都有包裹它的 window,而这个 window 是 top window 的子窗口。contentWindow属性返回元素的Window对象。你可以使用这个Window对象来访问iframe的文档及其内部DOM。

下述用端口:10000表示 — domainA;10001表示 — domainB

<!-- localhost:10000 -->
<script>
  var iframe = document.createElement('iframe');
  iframe.style.display = 'none'; // 隐藏

  var state = 0; // 防止页面无限刷新
  iframe.onload = function() {
      if(state === 1) {
          console.log(JSON.parse(iframe.contentWindow.name));
          // 清除创建的iframe
          iframe.contentWindow.document.write('');
          iframe.contentWindow.close();
          document.body.removeChild(iframe);
      } else if(state === 0) {
          state = 1;
          // 加载完成,指向当前域,防止错误(proxy.html为空白页面)
          // Blocked a frame with origin "http://localhost:10000" from accessing a cross-origin frame.
          iframe.contentWindow.location = 'http://localhost:10000/proxy.html';
      }
  };

  iframe.src = 'http://localhost:10001';
  document.body.appendChild(iframe);
</script>

<!-- localhost:10001 -->
<!DOCTYPE html>
...
<script>
  window.name = JSON.stringify({a: 1, b: 2});
</script>
</html>

注意:

直接嵌入其他域(localhots:10001)下的URL会报错,所以需要加载完成替换为当前域的URL(localhots:10000),proxy.html为空白页面,只为解决该问题;
在这里插入图片描述
重新设置 src(http://localhost:10000/proxy.html)后导致页面不断刷新,所以通过 state 来控制;
全部获取完结果后,清除该 iframe。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值