前端跨了个域

当我们谈论前端跨域时,我们到底在说什么?

iframe 跨域

在使用上来说,iframe 跨域是比较麻烦的一种(创建新元素 -> 处理跨域交互),但是伟大的邓小平同志说过:

不管是黑猫还是白猫,只要能抓住老鼠,就是好猫。

所以,作为一种经典的跨域方式,还是要把它单独提溜出来念叨念叨。 根据使用场景和方式的不同,iframe 跨域分为以下几种:

  • document.domain
  • location.hash
  • postMessage

document.domain

适用场景:不同子域,相同主域 举个栗子,有两个 url,分别是:https://kyrieliu.cn/a.htmlhttp://www.kyrieliu.cn/b.html(主域是相同的)。 这个时候,b 页面通过 iframe 内嵌在 a 页面中,iframe 的 onload 事件是由 a 中的脚本制定的函数,用以获取 b 中的某个全局变量。 需要将二者的 document.domian 同时设置为 kyrieliu.cn 即可完成这一次的跨域。

location.hash

一个页面和从属于它的 iframe 之间可以互相读取和修改 URL,但还是有一定的前提:父窗口对子窗口进行 url 的读写时,随意;子窗口对父窗口的 url 进行读写时,受到同源策略的限制。所以在这种情况下,子窗口需要借助一个“代理窗口”去修改父窗口的 url。 通信的交互过程如上。 接下来再讨论为什么 hash 可以实现传递数据的需求。 对于每一个 url 来说,hash 就是 # 后面的部分,这一部分通常用来做当前页面的锚点定位,所以服务器(后端)是不会关心这一部分的,从而可以交给前端来搞一些“骚操作”。但也有一个不可避免的缺点:会造成一些不必要的 history 记录。

大致实现

比如在 url 为 kyrieliu.cn/index.html 的页面 A 内 append 了一个 src 为 google.com/index.html 的 iframe。

  • A 向 iframe 传递数据
    1. A 中直接修改 iframe 的 src 为 google.com/index.html#name=kyrieliu
    2. iframe 中通过 hashchange 事件即可拿到数据
  • iframe 向 A 传递数据
    1. iframe 中再创建一个 iframe,后者的 src 和 A 同源并且通过 hash 带上想要传递的数据,如:kyrieliu.cn/proxy.html#age=23
    2. 子 iframe 通过 parent.parent.location.hash = self.location.hash.substring(1)将数据传递给 A
    3. A 通过 hashchange 事件拿到对应的数据

postMessage

这个方法就比较简洁明了:父窗口和子窗口都可以作为数据的发送方和接收方,且不需要考虑是否同源。还是用上面的栗子,比如现在需要从父窗口向子窗口发送数据:

// A.js
const iframe = document.querySelector('#iframe');
const targetOrigin = 'google.com';
iframe.contentWindow.postMessage('hello', targetOrigin);

// iframe.js
window.addEventListener('message', function(ev){
    // 验证发送方
    if (ev.origin === 'kyrieliu.cn') {
        console.log(ev.data);
    }
}, false);

这里注意 postMessage 的调用方式: whichWindow.postMessage(message, targetOrigin);

JSONP 跨域

这是一种古老且稳定的跨域方式,兼容性好,但只支持获取数据(GET)。它的原理是:

  1. 前端通过 <script> 的形式向后端发起请求,并在参数中告知将用于处理数据的函数名,同时在前端定义这个函数。
  2. 后端返回的不是纯数据,而是用前端告知的函数名包裹数据,传递到前端以后也就变成了一段可执行的 js 代码

CORS 跨域

CORS(Cross Origin Resource Sharing)的中心思想是:通过自定义的 HTTP Header 让浏览器和服务器进行“沟通”,决定本次请求的成功与否。 一般情况下,前端开发人员需要做的就是:

  1. 找到对接的后端大佬
  2. 对他说:“老哥,帮我设置一下跨域头(Access-Control-Allow-Origin)”

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何发布一个自己的 node package?

    伴随着 Node 的兴起,npm 成为了前端工程中的模块小管家。当攻城狮们要在项目中使用第三方的开源框架或工具时,一行 npm install 就能把需要的东西...

    kyrieliu
  • VSCode 真香

    Sublime 简直是前端 coding 神器 什么需求都能满足 我这辈子就用 Sublime 了 嗯,VScode 真香!

    kyrieliu
  • 移动端调试杀手锏

    今天,哦不,昨天,是让人惊喜的一天。这惊喜当然不是来自于日常工作,而是来自于开源社区。 移动端调试在几年前可能还是前端开发的一个痛点,不过随着开发工具的不断完善...

    kyrieliu
  • JQuery iframe宽高度自适应浏览器窗口大小的解决方法

    https://gitee.com/ishouke/front_end_plugin/blob/master/jquery-3.2.1.min.js

    授客
  • 菜鸟必备的循环神经网络指南

    An Introduction to Recurrent Neural Networks for Beginners

    昱良
  • 2013年十大热门国内科技公司

    纽约时报中文网1月13日首发 2013年对于中国科技行业来说是一个结合之年。软件和硬件、线上和线下、互联网和传统企业、PC(个人电脑)和移动互联网、传统...

    罗超频道
  • 独家 | 菜鸟必备的循环神经网络指南(附链接)

    本文将介绍最基础的循环神经网络(Vanilla RNNs)的概况,工作原理,以及如何在Python中实现。

    数据派THU
  • 「R」数据可视化6 : 曼哈顿图

    在生物信息领域我们常常使用R语言对数据可视化。在对数据可视化的时候,我们需要明确想要展示的信息,从而选择最为合适的图突出该信息。本系列文章将介绍多种基于不同R包...

    王诗翔呀
  • Python的dict()函数

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    于小勇
  • Geneshot (上): 我的这个研究方向到底有哪些基因被研究过?

    重要的事情说在前面:这个网站有时候检索不了,这个时候最好科学上网。请结合自身合理选择。

    匹咔球

扫码关注云+社区

领取腾讯云代金券